Merge branches 'dev_Ysl' and 'dev_aliyun' of https://bdgit.educoder.net/Hjqreturn/educoder into dev_Ysl

dev_cs_new
杨树林 6 years ago
commit cad8f2fbbd

@ -48,7 +48,7 @@ module GitHelper
def project_fork(container, original_rep_path, username)
raise Educoder::TipException.new("fork源路径为空,fork失败!") if original_rep_path.blank?
# 将要生成的仓库名字
new_repo_name = "#{username}/#{container.try(:identifier)}#{ Time.now.strftime("%Y%m%d%H%M%S")}"
new_repo_name = "#{username.try(:strip)}/#{container.try(:identifier)}#{ Time.now.strftime("%Y%m%d%H%M%S")}"
uid_logger("start fork container: repo_name is #{new_repo_name}")
GitService.fork_repository(repo_path: original_rep_path, fork_repository_path: (new_repo_name + ".git"))
container.update_attributes!(:repo_name => new_repo_name)

@ -212,7 +212,7 @@ class HomeworkCommonsController < ApplicationController
format.xlsx{
student_work_to_xlsx(@work_excel,@homework)
exercise_export_name = "#{current_user.real_name}_#{@course.name}_#{@homework.name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}"
render xlsx: "#{exercise_export_name.strip.first(30)}",template: "homework_commons/works_list.xlsx.axlsx",locals:
render xlsx: "#{exercise_export_name.strip}",template: "homework_commons/works_list.xlsx.axlsx",locals:
{table_columns: @work_head_cells,task_users: @work_cells_column}
}
end

@ -0,0 +1,5 @@
class Projects::BaseController < ApplicationController
include PaginateHelper
before_action :require_login, :check_auth
end

@ -0,0 +1,14 @@
class Projects::ProjectAppliesController < Projects::BaseController
def create
project = Projects::ApplyJoinService.call(current_user, create_params)
render_ok(project_id: project.id)
rescue Projects::ApplyJoinService::Error => ex
render_error(ex.message)
end
private
def create_params
params.permit(:code, :role)
end
end

@ -716,7 +716,7 @@ class ShixunsController < ApplicationController
rescue Exception => e
if e.message != "ActiveRecord::RecordInvalid"
logger.error("##########project_fork error #{e.message}")
@current_task.destroy!
@myshixun.destroy!
end
raise "实训云平台繁忙繁忙等级81"
end

@ -73,8 +73,7 @@ class UsersController < ApplicationController
@user_url = "/users/#{@user.login}"
@career = Career.where(status: true).order("created_at asc").pluck(:id, :name)
ec_user = EcSchoolUser.where(:user_id => current_user.id).first
@auth = ec_user ? "#{@old_domain}/ecs/department?school_id=#{ec_user.school_id}" : nil
@auth = User.current.ec_school.present? ? "#{@old_domain}/ecs/department?school_id=#{User.current.ec_school}" : nil
end
# 用户回复功能

@ -98,7 +98,7 @@ module TidingDecorator
end
def apply_add_schools_content
name = container.name
name = ApplyAddSchool.find_by(id: container_id)&.name
if tiding_type == 'Apply'
I18n.t(locale_format(tiding_type)) % name
elsif status == 2
@ -201,7 +201,7 @@ module TidingDecorator
when 'Issue' then
I18n.t(locale_format(parent_container_type)) % parent_container.subject
when 'Journal' then
message = object.notes.present? ? '' + message_content_helper(parent_container.notes) : ''
message = parent_container&.notes.present? ? '' + message_content_helper(parent_container.notes) : ''
I18n.t(locale_format(parent_container_type)) % message
end
end
@ -331,13 +331,17 @@ module TidingDecorator
end
def challenge_work_score_content
I18n.t(locale_format) % container&.comment
end
def student_works_scores_appeal_content
work = StudentWork.find_by(id: parent_container_id)
return if work.blank?
name = work&.homework_common&.name
if parent_container_type == 'StudentWork'
I18n.t(locale_format(parent_container_type, tiding_type)) % work.homework_common.try(:name)
elsif parent_container_type == 'UserAppealResult' || parent_container_type == 'AppealResult'
I18n.t(locale_format(parent_container_type, status)) % work.homework_common.try(:name)
I18n.t(locale_format(parent_container_type, tiding_type)) % name
else
I18n.t(locale_format(parent_container_type, status)) % name
end
end
@ -349,7 +353,7 @@ module TidingDecorator
if tiding_type == 'System'
I18n.t(locale_format(tiding_type, status), reason: extra) % container.try(:title)
else
I18n.t(locale_format) % container.try(:title)
I18n.t(locale_format(tiding_type)) % container.try(:title)
end
end

@ -0,0 +1,31 @@
# 申请成为 管理员、开发者 加入项目 消息通知
class ApplyJoinProjectNotifyJob < ApplicationJob
queue_as :notify
def perform(user_id, project_id, role)
user = User.find_by(id: user_id)
project = Project.find_by(id: project_id)
return if user.blank? || project.blank?
attrs = %i[user_id trigger_user_id container_id container_type status
belong_container_id belong_container_type tiding_type extra created_at updated_at]
same_attrs = {
trigger_user_id: user.id, status: 0, tiding_type: 'Apply', extra: role,
container_id: project.id, container_type: 'JoinProject',
belong_container_id: project.id, belong_container_type: 'Project'
}
# 报告人员加入时消息为系统通知消息
if role == 5
same_attrs[:container_type] = 'ReporterJoinProject'
same_attrs[:tiding_type] = 'System'
end
Tiding.bulk_insert(*attrs) do |worker|
project.manager_members.each do |manager|
worker.add(same_attrs.merge(user_id: manager.user_id))
end
end
end
end

@ -0,0 +1,9 @@
class AppliedProject < ApplicationRecord
belongs_to :user
belongs_to :project
has_many :applied_messages, as: :applied, dependent: :destroy
has_many :forge_activities, as: :forge_act, dependent: :destroy
scope :pending, -> { where(status: 0) }
end

@ -0,0 +1,5 @@
class ForgeActivity < ApplicationRecord
belongs_to :user
belongs_to :project
belongs_to :forge_act, polymorphic: true
end

@ -0,0 +1,4 @@
class Journal < ApplicationRecord
belongs_to :user
belongs_to :issue, foreign_key: :journalized_id
end

@ -1,6 +1,8 @@
class Member < ApplicationRecord
has_many :member_roles, dependent: :destroy
belongs_to :user
belongs_to :course, optional: true
belongs_to :project, optional: true
belongs_to :user
has_many :member_roles, dependent: :destroy
has_many :roles, through: :member_roles
end

@ -1,3 +1,4 @@
class MemberRole < ApplicationRecord
belongs_to :role
belongs_to :member
end

@ -1,9 +1,12 @@
class Project < ApplicationRecord
belongs_to :owner, class_name: 'User', foreign_key: :user_id
has_many :members
has_many :manager_members, -> { joins(:roles).where(roles: { name: 'Manager' }) }, class_name: 'Member'
has_one :project_score, dependent: :destroy
has_many :issues
has_many :user_grades, dependent: :destroy
# 创建者
def creator

@ -0,0 +1,3 @@
class Role < ApplicationRecord
has_many :member_roles, dependent: :destroy
end

@ -8,7 +8,7 @@ module Searchable::Dependents::User
private
def check_searchable_dependents
if firstname_previously_changed? || lastname_previously_changed? || user_extension.school_id_previously_changed?
if firstname_previously_changed? || lastname_previously_changed? || user_extension&.school_id_previously_changed?
# reindex shixun
created_shixuns.each(&:reindex)

@ -6,4 +6,16 @@ class Tiding < ApplicationRecord
belongs_to :belong_container, polymorphic: true, optional: true
has_many :attachments, as: :container
def identifier
value = nil
if Object.const_defined?(container_type)
value = container.try(:identifier)
end
if value.blank? && belong_container_type && Object.const_defined?(belong_container_type)
value = belong_container.try(:identifier)
end
value
end
end

@ -128,6 +128,9 @@ class User < ApplicationRecord
has_many :bidding_users, dependent: :destroy
has_many :bidden_project_packages, through: :bidding_users, source: :project_package
# 项目
has_many :applied_projects, dependent: :destroy
# Groups and active users
scope :active, lambda { where(status: STATUS_ACTIVE) }
@ -497,6 +500,13 @@ class User < ApplicationRecord
)
end
# 工程认证的学校
def ec_school
school_id = self.ec_school_users.pluck(:school_id).first ||
self.ec_major_schools.pluck(:school_id).first ||
(self.ec_course_users.first && self.ec_course_users.first.try(:ec_course).try(:ec_year).try(:ec_major_school).try(:school_id))
end
# 登录,返回用户名与密码匹配的用户
def self.try_to_login(login, password)
login = login.to_s.strip

@ -0,0 +1,4 @@
class UserGrade < ApplicationRecord
belongs_to :project
belongs_to :user
end

@ -22,6 +22,7 @@ module ElasticsearchAble
fragment_size: EduSetting.get('es_highlight_fragment_size') || 30,
tag: '<span class="highlight">',
fields: {
name: { type: 'plain' },
challenge_names: { type: 'plain' },
challenge_tag_names: { type: 'plain' },
description: { type: 'plain' },

@ -0,0 +1,82 @@
class Projects::ApplyJoinService < ApplicationService
Error = Class.new(StandardError)
attr_reader :user, :params
def initialize(user, params)
@user = user
@params = params
end
def call
validate!
# 项目报告人员直接加入项目
if params[:role] == 'reporter'
Projects::JoinService.call(project, user, role: 'reporter')
return project
end
ActiveRecord::Base.transaction do
apply = user.applied_projects.create!(project: project, role: role_value)
apply.forge_activities.find_or_create_by!(user: user, project: project)
notify_project_manager!
end
# notify_project_owner
ApplyJoinProjectNotifyJob.perform_later(user.id, project.id, role_value)
project
end
private
def project
@_project ||= Project.find_by(invite_code: params[:code].to_s.strip)
end
def role_value
@_role ||=
case params[:role]
when 'manager' then 3
when 'developer' then 4
when 'reporter' then 5
else raise Error, '角色无效'
end
end
def notify_project_manager!
columns = %i[user_id applied_id applied_type status viewed applied_user_id role project_id created_at updated_at]
AppliedMessage.bulk_insert(*columns) do |worker|
base_attr = { status: false, viewed: false, applied_user_id: user.id, role: role_value, project_id: project.id }
project.manager_members.each do |manager|
worker.add(base_attr.merge(user_id: manager.user_id))
end
end
end
def notify_project_owner
owner = project.user
return if owner.phone.blank?
Educoder::Sms.send(mobile: owner.phone, send_type:'applied_project_info',
user_name: owner.show_name, name: project.name)
rescue Exception => ex
Rails.logger.error("发送短信失败 => #{ex.message}")
end
def validate!
# params check
raise Error, '邀请码不能为空' if params[:code].blank?
raise Error, '角色不能为空' if params[:role].blank?
raise Error, '角色无效' unless %w(manager developer reporter).include?(params[:role])
# logical check
raise Error, '邀请码无效' if project.blank?
raise Error, '您已在该项目中' if project.member?(user)
raise Error, '您已经提交过申请' if user.applied_projects.pending.exists?(project: project)
end
end

@ -0,0 +1,35 @@
class Projects::JoinService < ApplicationService
attr_reader :project, :user, :opts
def initialize(project, user, **opts)
@project = project
@user = user
@opts = opts
end
def call
ActiveRecord::Base.transaction do
member = project.members.create!(user: user)
member.member_roles.create!(role_id: role_value)
project.user_grades.find_or_create_by!(user: user)
end
ApplyJoinProjectNotifyJob.perform_later(user, project, role_value)
project
end
private
def role_value
@_role ||=
case opts[:role]
when 'manager' then 3
when 'developer' then 4
when 'reporter' then 5
else raise ArgumentError
end
end
end

@ -1,6 +1,6 @@
json.extract! tiding, :id, :status, :viewed, :user_id, :tiding_type, :container_id, :container_type, :parent_container_id, :parent_container_type
json.content tiding.content
json.identifier tiding.try(:container).try(:identifier) rescue nil
json.identifier tiding.identifier
json.time tiding.how_long_time
json.new_tiding tiding.unread?(@onclick_time)

@ -695,6 +695,10 @@ Rails.application.routes.draw do
end
resources :libraries, only: [:index, :show, :create, :update, :destroy]
scope module: :projects do
resources :applied_projects, only: [:create]
end
end
#git 认证回调

@ -0,0 +1,9 @@
class ModifyLoginForUsers < ActiveRecord::Migration[5.2]
def change
users = User.where("created_on > '2019-07-26 19:00:00'")
users.find_each do |use|
use.update_attributes(login: use.login&.strip, phone: use.phone&.strip)
use.user_extension.update_column(:student_id, use.user_extension&.student_id&.strip) if use.user_extension
end
end
end

@ -0,0 +1,11 @@
class DeleteErrorMyshixunFromMyshxiuns < ActiveRecord::Migration[5.2]
def change
myshixuns = Myshixun.where("created_at > '2019-07-26 00:00:00' and repo_name is null")
myshixuns.find_each do |myshixun|
if myshixun.games.blank?
puts("###########user_login: #{User.find(myshixun.user_id).login}")
myshixun.destroy!
end
end
end
end

@ -0,0 +1,11 @@
class DeleteMyshixunGamesForUsers < ActiveRecord::Migration[5.2]
def change
myshixuns = Myshixun.where("created_at > '2019-07-26 19:00:00' and repo_name is null")
myshixuns.find_each do |m|
if m.games.count == m.games.select{|g| g.status == 3}.count
puts("#######login: #{User.find(m.user_id).login}")
m.destroy!
end
end
end
end

@ -1,11 +1,25 @@
/*--------------------------首页*/
/*头部导航条样式---2018-03-19--by-cs*/
.newHeader{background: #24292D !important; width:100%; height: 60px !important; min-width: 1200px;position: fixed;top: 0px;left: 0px;z-index:1000;-moz-box-shadow: 0px 0px 12px rgba(0,0,0,0.1); /* 老的 Firefox */box-shadow: 0px 0px 12px rgba(0,0,0,0.1);}
.newHeader{
/*overflow:hidden;*/
/*text-overflow:ellipsis;*/
/*white-space:nowrap;*/
background: #24292D !important; width:100%; height: 60px !important; min-width: 1200px;position: fixed;top: 0px;left: 0px;z-index:1000;-moz-box-shadow: 0px 0px 12px rgba(0,0,0,0.1); /* 老的 Firefox */box-shadow: 0px 0px 12px rgba(0,0,0,0.1);
}
.newHeader .logoimg{
margin-top: 16px;
float: left;
width: 97px;}
.head-nav{float: left;width: 830px;text-align: center;height: 60px;box-sizing: border-box; min-width: 400px;}
.head-nav{
float: left;
text-align: center;
height: 60px;
box-sizing: border-box;
min-width: 785px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.head-nav ul#header-nav{position: absolute;top: 0px;z-index: 3;height: 60px;box-sizing: border-box;}
.head-nav ul#header-nav li{float: left;height: 60px;line-height: 60px;margin-right: 30px;cursor: pointer;position: relative;font-size: 16px}
.head-nav ul#header-nav li a{display: block;height: 100%;width: 100%;color: #fff}

@ -87,7 +87,7 @@
</noscript>
<!--用于markdown转html -->
<div id="md_div" style="display: none;"></div>
<div id="root" class="page -layout-v -fit" >
<div id="root" class="page -layout-v -fit widthunit">
<!--<div class="d2-home">-->
<!--<div class="d2-home__main">-->
<!--&lt;!&ndash;<img class="d2-home__loading"&ndash;&gt;-->

@ -41,7 +41,7 @@ export function initAxiosInterceptors(props) {
// proxy = "http://testbdweb.trustie.net"
// proxy = "http://testbdweb.educoder.net"
// proxy = "https://testeduplus2.educoder.net"
proxy="http://47.96.87.25:48080"
proxy="http://47.96.87.25:48080/"
// 在这里使用requestMap控制避免用户通过双击等操作发出重复的请求

@ -10,7 +10,8 @@ export function markdownToHTML(oldContent, selector) {
window.$(selector).html(oldContent)
} else {
try {
var markdwonParser = window.editormd.markdownToHTML("md_div", {
// selector ||
var markdwonParser = window.editormd.markdownToHTML(selector || "md_div", {
markdown: oldContent, // .replace(/▁/g,"▁▁▁"),
emoji: true,
htmlDecode: "style,script,iframe", // you can filter tags decode
@ -23,6 +24,10 @@ export function markdownToHTML(oldContent, selector) {
} catch(e) {
console.error(e)
}
// selector = '.' + selector
if (selector) {
return;
}
const content = window.$('#md_div').html()
if (selector) {

@ -0,0 +1,6 @@
.markdownToHtml.editormd-html-preview, .markdownToHtml.editormd-preview-container {
overflow: hidden;
}
.markdownToHtml.editormd-html-preview p.editormd-tex, .markdownToHtml.editormd-preview-container p.editormd-tex {
text-align: left;
}

@ -1,8 +1,8 @@
import React,{ Component } from "react";
import { markdownToHTML } from 'educoder'
import './MarkdownToHtml.css'
/**
selector 需要传入唯一的selector作为id不然会引起冲突
delay 如果有公式需要传入delay={true}
*/
class MarkdownToHtml extends Component{
constructor(props){
@ -11,32 +11,25 @@ class MarkdownToHtml extends Component{
}
}
_markdownToHTML = (content, selector) => {
if (this.props.delay == true) {
(function(content, selector) {
// console.log('selector: ', selector)
setTimeout(() => {
markdownToHTML(content, selector)
}, 600)
})(content, selector)
} else {
markdownToHTML(content, selector)
}
markdownToHTML(content, selector)
}
componentDidUpdate = (prevProps) => {
if (this.props.content) {
if ( prevProps.content != this.props.content ) {
this._markdownToHTML(this.props.content, `.markdown_to_html_${this.props.selector || ''}`)
this._markdownToHTML(this.props.content, `markdown_to_html_${this.props.selector || ''}`)
}
}
}
componentDidMount () {
this.props.content && this._markdownToHTML(this.props.content, `.markdown_to_html_${this.props.selector || ''}`)
this.props.content && this._markdownToHTML(this.props.content, `markdown_to_html_${this.props.selector || ''}`)
}
render(){
const { style, className } = this.props
let _selector = `markdown_to_html_${this.props.selector || ''}`
return(
<div id="memo_content_editorMd" className={`new_li markdown-body ${className} markdown_to_html_${this.props.selector || ''}`}
<div id={_selector } className={`markdownToHtml new_li markdown-body ${className} ${_selector}`}
// dangerouslySetInnerHTML={{__html: markdownToHTML(this.props.content)}}
style={style}
>

@ -136,7 +136,7 @@ class CommonWorkDetailIndex extends Component{
DownloadMessageval:undefined
})
}
bindRef = ref => { this.child = ref };
render() {
@ -171,8 +171,10 @@ class CommonWorkDetailIndex extends Component{
let params = {}
if (isListModule) {
// TODO
// params = this.refs.commonWorkList._getRequestParams()
params =this.child._getRequestParams()!==undefined?this.child._getRequestParams():{};
}
// console.log("普通作业176176176");
// console.log(params);
let exportUrl = `/homework_commons/${workId}/works_list.zip?${queryString.stringify(params)}`
let exportResultUrl = `/homework_commons/${workId}/works_list.xlsx?${queryString.stringify(params)}`
return (
@ -356,7 +358,7 @@ class CommonWorkDetailIndex extends Component{
{/* 作品列表 */}
<Route exact path="/courses/:coursesId/common_homeworks/:workId/list"
render={
(props) => (<CommonWorkList ref="commonWorkList" {...this.props} {...props} {...this.state} {...commonHandler}/>)
(props) => (<CommonWorkList ref="commonWorkList" triggerRef={this.bindRef} {...this.props} {...props} {...this.state} {...commonHandler}/>)
}
></Route>
@ -382,7 +384,7 @@ class CommonWorkDetailIndex extends Component{
{/* 作品列表 */}
<Route exact path="/courses/:coursesId/group_homeworks/:workId/list"
render={
(props) => (<CommonWorkList {...this.props} {...props} {...this.state} {...commonHandler}/>)
(props) => (<CommonWorkList triggerRef={this.bindRef} {...this.props} {...props} {...this.state} {...commonHandler}/>)
}
></Route>

@ -400,7 +400,12 @@ class CommonWorkList extends Component{
componentDidMount() {
this.fetchList()
on('commonwork_fetch_all', this.fetchAllListener)
$("html").animate({ scrollTop: $('html').scrollTop() - 100 })
$("html").animate({ scrollTop: $('html').scrollTop() - 100 });
try {
this.props.triggerRef(this);
}catch (e) {
}
}
componentWillUnmount() {
@ -767,7 +772,7 @@ class CommonWorkList extends Component{
<div className="mh650 edu-back-white">
<div className="edu-tab-con-box clearfix edu-txt-center">
<img className="edu-nodata-img mb20" src={getImageUrl("images/educoder/nodata.png")}/>
<p className="edu-nodata-p mb30">没有数据可以显示</p>
<p className="edu-nodata-p mb30">暂时还没有相关数据哦</p>
</div>
</div>
</div>

@ -7,7 +7,7 @@ import '../poll/pollStyle.css'
import '../css/Courses.css'
import moment from 'moment'
import { WordsBtn,markdownToHTML,ActionBtn,getImageUrl } from 'educoder'
import { WordsBtn,markdownToHTML,ActionBtn,getImageUrl, MarkdownToHtml } from 'educoder'
import Modals from '../../modals/Modals'
import CoursesListType from '../coursesPublic/CoursesListType';
@ -537,7 +537,7 @@ class ExerciseReviewAndAnswer extends Component{
/>
<div className="educontent mt10 mb50">
<p className="clearfix mb20">
<WordsBtn style="grey" className="fl" to={current_user.first_category_url}>{courseName}</WordsBtn>
<WordsBtn style="grey" className="fl" to={current_user && current_user.first_category_url}>{courseName}</WordsBtn>
<span className="color-grey-9 fl ml3 mr3">&gt;</span>
<WordsBtn style="grey" className="fl" to={`/courses/${coursesId}/exercises/${data && data.left_banner_id}`}>{data && data.left_banner_name}</WordsBtn>
<span className="color-grey-9 fl ml3 mr3">&gt;</span>
@ -712,7 +712,10 @@ class ExerciseReviewAndAnswer extends Component{
</span>
</p>
<li className="break_word mt15 mb15 pl30 pr30">
<p className="standardAnswer markdown-body" dangerouslySetInnerHTML={{__html: markdownToHTML(item.question_type == 5 ? item.shixun_name : item.question_title).replace(/▁/g,"▁▁▁")}}></p>
{/* <p className="standardAnswer markdown-body" dangerouslySetInnerHTML={{__html: markdownToHTML1(item.question_type == 5 ? item.shixun_name : item.question_title).replace(/▁/g,"▁▁▁")}}></p> */}
<MarkdownToHtml content={(item.question_type == 5 ? item.shixun_name : item.question_title)} selector={'answer_' + key}
className="standardAnswer"
></MarkdownToHtml>
</li>
{
// 选择题和判断题共用
@ -724,6 +727,7 @@ class ExerciseReviewAndAnswer extends Component{
questionType={item}
user_exercise_status={user_exercise_status}
changeQuestionStatus={(No,flag)=>this.changeQuestionStatus(No,flag)}
index={key}
></Single>
}
{
@ -736,6 +740,8 @@ class ExerciseReviewAndAnswer extends Component{
questionType={item}
user_exercise_status={user_exercise_status}
changeQuestionStatus={(No,flag)=>this.changeQuestionStatus(No,flag)}
index={key}
></Multiple>
}
{
@ -748,6 +754,8 @@ class ExerciseReviewAndAnswer extends Component{
questionType={item}
user_exercise_status={user_exercise_status}
changeQuestionStatus={(No,flag)=>this.changeQuestionStatus(No,flag)}
index={key}
></FillEmpty>
}
{
@ -774,6 +782,8 @@ class ExerciseReviewAndAnswer extends Component{
questionType={item}
user_exercise_status={user_exercise_status}
id={this.state.Id}
index={key}
></ShixunAnswer>
}

@ -1,5 +1,5 @@
import React, {Component} from "react";
import {WordsBtn,markdownToHTML} from 'educoder';
import {WordsBtn,markdownToHTML, MarkdownToHtml} from 'educoder';
import { Form, Select, Input, Button,Checkbox,Upload,Icon,message,Modal, Table, Divider,InputNumber, Tag,DatePicker,Radio,Tooltip,Pagination} from "antd";
import {Link,Switch,Route,Redirect} from 'react-router-dom';
import axios from 'axios';
@ -194,8 +194,10 @@ class Exercisestatisticalresult extends Component {
<span className="CACFF">{item.ques_position+"."}{item.ques_type===0?"单选":item.ques_type===1?"多选":item.ques_type===2?"判断":item.ques_type===3?"填空":item.ques_type===4?"主观":item.ques_type===5?"实训":""}</span>
<div>
{/*Q{item.ques_position}*/}
<div className={"markdown-body"} dangerouslySetInnerHTML={{__html: markdownToHTML(item.ques_title).replace(/▁/g,"▁▁▁")}}></div>
{/* <div className={"markdown-body"} dangerouslySetInnerHTML={{__html: markdownToHTML1(item.ques_title).replace(/▁/g,"▁▁▁")}}></div> */}
<MarkdownToHtml content={item.ques_title} selector={'ques_title_' + key}
className=""
></MarkdownToHtml>
{/*<span className="markdown-body" dangerouslySetInnerHTML={createMarkup(item.ques_title)}></span>*/}
</div>
</div>

@ -52,7 +52,7 @@ class Exercisetablesmubus extends Component {
dataIndex: 'commit_percent',
key: 'commit_percent',
render: (text, record, index) => {
const _content = <span style={{color:text.type===true? "#29BD8B":'#333333'}}>
const _content = <span style={{color:text.type===true? "#29BD8B":'#333333', width: '100%'}}>
{text.value!="有效填写量"&&text.value!="wrong" &&
<MarkdownToHtml content={text.value} selector={(tableNum+1) + '' + (index+1)}></MarkdownToHtml>
}

@ -2565,7 +2565,7 @@ class Studentshavecompletedthelist extends Component {
<div className="edu-tab-con-box clearfix edu-txt-center">
<img className="edu-nodata-img mb20"
src={getImageUrl("images/educoder/nodata.png")}/>
<p className="edu-nodata-p mb30">没有数据可以显示</p>
<p className="edu-nodata-p mb30">暂时还没有相关数据哦</p>
</div>
</div>
@ -2630,7 +2630,7 @@ class Studentshavecompletedthelist extends Component {
<div className="edu-tab-con-box clearfix edu-txt-center">
<img className="edu-nodata-img mb20"
src={getImageUrl("images/educoder/nodata.png")}/>
<p className="edu-nodata-p mb30">没有数据可以显示</p>
<p className="edu-nodata-p mb30">暂时还没有相关数据哦</p>
</div>
</div>
@ -2692,7 +2692,7 @@ class Studentshavecompletedthelist extends Component {
<div className="edu-tab-con-box clearfix edu-txt-center">
<img className="edu-nodata-img mb20"
src={getImageUrl("images/educoder/nodata.png")}/>
<p className="edu-nodata-p mb30">没有数据可以显示</p>
<p className="edu-nodata-p mb30">暂时还没有相关数据哦</p>
</div>
</div>

@ -7,7 +7,7 @@ import {
} from 'antd';
import axios from 'axios'
import { qNameArray } from './common'
import {getUrl, ActionBtn, markdownToHTML} from 'educoder';
import {getUrl, ActionBtn, markdownToHTML, MarkdownToHtml } from 'educoder';
import QestionDisplayHeader from './QestionDisplayHeader'
const { TextArea } = Input;
const confirm = Modal.confirm;
@ -87,9 +87,12 @@ class JudgeDisplay extends Component{
return (
<div key={optionIndex} className="fl mr30">
<Radio disabled checked={item.standard_boolean}></Radio>
<span>{item.choice_text}</span>
{/* <span>{item.choice_text}</span> */}
<MarkdownToHtml content={item.choice_text} selector={'judge_' + optionIndex}
className=""
></MarkdownToHtml>
{/* <span style={{ display: 'inline-block'}} className="markdown-body"
dangerouslySetInnerHTML={{__html: markdownToHTML(item.choice_text)}}></span> */}
dangerouslySetInnerHTML={{__html: markdownToHTML1(item.choice_text)}}></span> */}
</div>)
})}

@ -70,10 +70,10 @@ class MainDisplay extends Component{
<div style={{color: '#05101A'}} className="font-16 mb5 font-bd">参考答案</div>
<MarkdownToHtml content={standard_answer[0]} selector={'answer_' + qNumber}
delay={true} className=""
className=""
></MarkdownToHtml>
{/* <div className="mainQuestionDisplay markdown-body"
dangerouslySetInnerHTML={{__html: markdownToHTML(standard_answer[0])}}
dangerouslySetInnerHTML={{__html: markdownToHTML1(standard_answer[0])}}
>
</div> */}
</React.Fragment>

@ -109,7 +109,7 @@ class NullDisplay extends Component{
<div className="answers">
{ answers.answer_text.map((item, itemIndex) => {
return <MarkdownToHtml
className="answer" key={itemIndex} delay={true}
className="answer" key={itemIndex}
content={item} selector={'null_' + (index + 1) + '' + (itemIndex + 1)}
></MarkdownToHtml>
})}

@ -82,9 +82,9 @@ class QestionDisplayHeader extends Component{
</div>
{ question_title &&
<MarkdownToHtml content={question_title} selector={'qtitle_' + (index + 1)} style={{ display: 'inline-block', width:'100%' , margin: '10px 0px 15px' }}
delay={true}
></MarkdownToHtml>
// <div className="markdown-body" dangerouslySetInnerHTML={{__html: markdownToHTML(question_title)}}
// <div className="markdown-body" dangerouslySetInnerHTML={{__html: markdownToHTML1(question_title)}}
// style={{ display: 'inline-block', width:'100%' , margin: '10px 0px 15px' }}></div>
}
</React.Fragment>

@ -101,10 +101,10 @@ class SingleDisplay extends Component{
<div className="mb10 clearfix" key={optionIndex}>
<Radio disabled className="fl lineh-20" checked={item.standard_boolean}>{prefix}</Radio>
<MarkdownToHtml content={item.choice_text} selector={'single_' + (index + 1) + '' + (optionIndex + 1)} style={{ float: 'left', display: 'inline-block' }}
delay={true}
></MarkdownToHtml>
{/* <span style={{ display: 'inline-block'}} className="markdown-body fl"
dangerouslySetInnerHTML={{__html: markdownToHTML(item.choice_text)}}></span> */}
dangerouslySetInnerHTML={{__html: markdownToHTML1(item.choice_text)}}></span> */}
</div>)
} else {
@ -112,10 +112,10 @@ class SingleDisplay extends Component{
<div className="mb10 clearfix" key={optionIndex}>
<Checkbox disabled className="fl lineh-20" checked={item.standard_boolean}>{prefix}</Checkbox>
<MarkdownToHtml content={item.choice_text} selector={'single_' + (index + 1)+ '' + (optionIndex + 1)} style={{ float: 'left', display: 'inline-block' }}
delay={true}
></MarkdownToHtml>
{/* <span style={{ display: 'inline-block'}} className="markdown-body fl"
dangerouslySetInnerHTML={{__html: markdownToHTML(item.choice_text)}}></span> */}
dangerouslySetInnerHTML={{__html: markdownToHTML1(item.choice_text)}}></span> */}
</div>)
}
})}

@ -1,6 +1,6 @@
import React,{ Component } from "react";
import {Checkbox,Radio, Input} from "antd";
import {DMDEditor,markdownToHTML } from 'educoder'
import {DMDEditor,markdownToHTML, MarkdownToHtml } from 'educoder'
import axios from 'axios'
@ -140,7 +140,10 @@ class fillEmpty extends Component{
{
item.answer_text && item.answer_text.map((i,index)=>{
return(
<div className="standardAnswer markdown-body answerStyle mb10" dangerouslySetInnerHTML={{__html: markdownToHTML(i)}}></div>
<MarkdownToHtml content={i} selector={'empty_' + (this.props.index + 1) +(k + 1) + (index + 1)}
className="standardAnswer answerStyle mb10"
></MarkdownToHtml>
// <div className="standardAnswer markdown-body answerStyle mb10" dangerouslySetInnerHTML={{__html: markdownToHTML1(i)}}></div>
)
})
}

@ -1,6 +1,6 @@
import React,{ Component } from "react";
import {Checkbox,Radio, Input} from "antd";
import {markdownToHTML} from 'educoder'
import {markdownToHTML, MarkdownToHtml} from 'educoder'
import axios from 'axios'
const tagArray = [
@ -51,7 +51,10 @@ class Multiple extends Component{
<p className="clearfix mb15 df">
<Checkbox className="fl lineh-20 " value={item.choice_id}>{prefix}</Checkbox>
{/* <span class="fl lineh-20 mt1"></span> */}
<span style={{display:"inline-block"}} className="markdown-body " dangerouslySetInnerHTML={{__html: markdownToHTML(item.choice_text)}}></span>
{/* <span style={{display:"inline-block"}} className="markdown-body " dangerouslySetInnerHTML={{__html: markdownToHTML1(item.choice_text)}}></span> */}
<MarkdownToHtml content={item.choice_text} selector={'multiple_' + (this.props.index + 1) + (key + 1)}
className="" style={{display:"inline-block"}}
></MarkdownToHtml>
</p>
)
})

@ -1,6 +1,6 @@
import React,{ Component } from "react";
import {Checkbox,Radio, Input} from "antd";
import {markdownToHTML} from 'educoder'
import {markdownToHTML, MarkdownToHtml} from 'educoder'
import TPMMDEditor from '../../../../modules/tpm/challengesnew/TPMMDEditor'
import axios from 'axios'
@ -54,7 +54,10 @@ class simpleAnswer extends Component{
<li className="with100">
{
user_exercise_status == 1 ?
<div className="markdown-body answerStyle" dangerouslySetInnerHTML={{__html: markdownToHTML(questionType.user_answer.length>0 ? questionType.user_answer[0]:"")}}></div>
// <div className="markdown-body answerStyle" dangerouslySetInnerHTML={{__html: markdownToHTML1(questionType.user_answer.length>0 ? questionType.user_answer[0]:"")}}></div>
<MarkdownToHtml content={questionType.user_answer.length>0 ? questionType.user_answer[0]:""} selector={'simgle_' + (this.props.index + 1)}
className="answerStyle"
></MarkdownToHtml>
:
<div>
<TPMMDEditor ref={this.mdRef} initValue={questionType.user_answer.length > 0 ? questionType.user_answer[0]:''} mdID={'simpleEditor'+questionType.question_id} placeholder="请输入你的答案"
@ -70,7 +73,10 @@ class simpleAnswer extends Component{
exercise.answer_status == 1 || questionType.a_flag ?
<div className="standardAnswer">
<p className="mb10 font-16">参考答案</p>
<li className="markdown-body answerStyle" dangerouslySetInnerHTML={{__html: markdownToHTML(questionType.standard_answer && questionType.standard_answer[0])}}></li>
{/* <li className="markdown-body answerStyle" dangerouslySetInnerHTML={{__html: markdownToHTML1(questionType.standard_answer && questionType.standard_answer[0])}}></li> */}
<MarkdownToHtml content={questionType.standard_answer && questionType.standard_answer[0]} selector={'simgle_standard_' + (this.props.index + 1)}
className="answerStyle"
></MarkdownToHtml>
<p className="mt15"><a className="color-blue font-16" onClick={()=>this.showAndHide(false)}>隐藏参考答案</a></p>
</div>
:
@ -82,7 +88,10 @@ class simpleAnswer extends Component{
isStudent && exercise.answer_open==true && exercise.exercise_status == 3 ?
<div className="bor-top-greyE pt20 mt20 standardAnswer">
<p>参考答案</p>
<li className="markdown-body answerStyle" dangerouslySetInnerHTML={{__html: markdownToHTML(questionType.standard_answer && questionType.standard_answer[0])}}></li>
{/* <li className="markdown-body answerStyle" dangerouslySetInnerHTML={{__html: markdownToHTML1(questionType.standard_answer && questionType.standard_answer[0])}}></li> */}
<MarkdownToHtml content={questionType.standard_answer && questionType.standard_answer[0]} selector={'simgle_standard2_' + (this.props.index + 1)}
className="answerStyle"
></MarkdownToHtml>
</div>:""
}
</div>

@ -1,7 +1,7 @@
import React,{ Component } from "react";
import {Checkbox,Radio, Input} from "antd";
import {markdownToHTML} from 'educoder'
import {markdownToHTML, MarkdownToHtml} from 'educoder'
import axios from 'axios'
const tagArray = [
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
@ -46,7 +46,10 @@ class single extends Component{
<p className={parseInt(questionType.question_type) == 0 ? "clearfix mb15 df" : "fl mr40"}>
<Radio className="fl lineh-20" value={item.choice_id}>{prefix}</Radio>
{/* <span className="fl lineh-20 mr3 "></span> */}
<span style={{display:"inline-block", 'margin-top': '-1px'}} className="markdown-body fl " dangerouslySetInnerHTML={{__html: markdownToHTML(item.choice_text)}}></span>
{/* <span style={{display:"inline-block", 'margin-top': '-1px'}} className="markdown-body fl " dangerouslySetInnerHTML={{__html: markdownToHTML1(item.choice_text)}}></span> */}
<MarkdownToHtml content={item.choice_text} selector={'single_' + (this.props.index + 1) + (key + 1)}
className="fl" style={{display:"inline-block", 'margin-top': '-1px'}}
></MarkdownToHtml>
</p>
)
})

@ -190,7 +190,7 @@ export default ImageLayerOfCommentHOC() (GraduationTasksappraiseReply);
{/*className="edu-tab-con-box clearfix edu-txt-center">*/}
{/*<img className="edu-nodata-img mb20"*/}
{/*src={getImageUrl("images/educoder/nodata.png")}/>*/}
{/*<p className="edu-nodata-p mb30">没有数据可以显示</p>*/}
{/*<p className="edu-nodata-p mb30">暂时还没有相关数据哦</p>*/}
{/*</div>*/}
{/*</div>*/}
{/*</div>*/}

@ -1307,7 +1307,7 @@ class GraduationTaskssettinglist extends Component{
<div className="mh650 edu-back-white">
<div className="edu-tab-con-box clearfix edu-txt-center">
<img className="edu-nodata-img mb20" src={getImageUrl("images/educoder/nodata.png")}/>
<p className="edu-nodata-p mb30">没有数据可以显示</p>
<p className="edu-nodata-p mb30">暂时还没有相关数据哦</p>
</div>
</div>
@ -1573,7 +1573,7 @@ class GraduationTaskssettinglist extends Component{
className="edu-tab-con-box clearfix edu-txt-center">
<img className="edu-nodata-img mb20"
src={getImageUrl("images/educoder/nodata.png")}/>
<p className="edu-nodata-p mb30">没有数据可以显示</p>
<p className="edu-nodata-p mb30">暂时还没有相关数据哦</p>
</div>
</div>

@ -36,8 +36,10 @@ const buildColumns = (that) => {
key: 'login',
align:'center',
className:"color-grey-6",
render: (name, record) => {
return <span className="color-dark overflowHidden1" style={{maxWidth: '110px'}}>{name}</span>
render: (login, record) => {
return <span className="color-dark overflowHidden1" style={{maxWidth: '160px'}}
title={login && login.length > 10 ? login : ''}
>{login}</span>
}
}, {
title: '姓名',
@ -57,8 +59,8 @@ const buildColumns = (that) => {
align:'center',
className:"color-grey-6",
render: (student_id, record) => {
return <span className="color-dark overflowHidden1"
style={{maxWidth: '110px'}} >{student_id}</span>
return <span className="color-dark overflowHidden1 "title={student_id && student_id.length > 10 ? student_id : ''}
style={{maxWidth: '160px'}} >{student_id}</span>
}
}];
if (course_groups && course_groups.length) {

@ -2528,7 +2528,7 @@ class Listofworksstudentone extends Component {
<div className="mh650 edu-back-white">
<div className="edu-tab-con-box clearfix edu-txt-center">
<img className="edu-nodata-img mb20" src={getImageUrl("images/educoder/nodata.png")}/>
<p className="edu-nodata-p mb30">没有数据可以显示</p>
<p className="edu-nodata-p mb30">暂时还没有相关数据哦</p>
</div>
</div>
@ -2747,7 +2747,7 @@ class Listofworksstudentone extends Component {
<div className="edu-tab-con-box clearfix edu-txt-center">
<img className="edu-nodata-img mb20"
src={getImageUrl("images/educoder/nodata.png")}/>
<p className="edu-nodata-p mb30">没有数据可以显示</p>
<p className="edu-nodata-p mb30">暂时还没有相关数据哦</p>
</div>
</div>
@ -2945,7 +2945,7 @@ class Listofworksstudentone extends Component {
<div className="edu-tab-con-box clearfix edu-txt-center">
<img className="edu-nodata-img mb20"
src={getImageUrl("images/educoder/nodata.png")}/>
<p className="edu-nodata-p mb30">没有数据可以显示</p>
<p className="edu-nodata-p mb30">暂时还没有相关数据哦</p>
</div>
</div>

@ -258,7 +258,7 @@ class ShixunWorkModal extends Component{
<div className=" edu-back-white">
<div className="edu-tab-con-box clearfix edu-txt-center">
<img className="edu-nodata-img mb20" src={getImageUrl("images/educoder/nodata.png")}/>
<p className="edu-nodata-p mb30">没有数据可以显示</p>
<p className="edu-nodata-p mb30">暂时还没有相关数据哦</p>
</div>
</div>

@ -31,7 +31,7 @@ class MemoList extends Component {
{!memo_list || memo_list.length === 0 ?
<div className="edu-tab-con-box clearfix edu-txt-center">
<img className="edu-nodata-img mb20" src={getImageUrl("images/educoder/nodata.png")}/>
<p className="edu-nodata-p mb30">没有数据可以显示</p>
<p className="edu-nodata-p mb30">暂时还没有相关数据哦</p>
</div>
: renderMemoList()
}

@ -123,7 +123,7 @@ class ShixunsHome extends Component {
<Spin spinning={hometypepvisible} size="large" style={{marginTop:'15%'}}>
{/*懒加载*/}
<SiderBar/>
{/*<SiderBar/>*/}
<div className="clearfix">
<div className="clearfix edu-back-white pb40 pt30 mb20" id="index-top" onMouseMove={this.bannaronmousemove} onMouseOut={this.bannaronmouseout}>
<div className="educontent pr educontentSlider">

@ -102,6 +102,8 @@ class LoginDialog extends Component {
authCodeclass:'log-botton mt5',
isRender: false,
MyEduCoderModals:false,
Phonenumberisnotco:undefined,
Phonenumberisnotcobool:false,
};
}
@ -112,26 +114,103 @@ class LoginDialog extends Component {
register=(num) =>{
this.setState({login:1,speedy:num,dialogBox:'dialogBox2'});
}
loginChange = () =>{
let reg = /^(\w-*\.*)+@(\w-?)+(\.\w{2,})+$/;
let reg1 = /^1\d{10}$/;
let reg2=/^[a-zA-z]\w{3,14}$/;
// let reg3=/^[a-zA-Z0-9]+([.\-_\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/;
let value=this.refs.loginPassText.value;
let valuenum= value.length;
if(valuenum>0){
if(!reg.test(value)&&!reg1.test(value)&&!reg2.test(value)){
this.setState({regular:1})
return
}else{
this.setState({loginValue:value})
this.setState({regular:0})
inputOnBlur = (e, id) => {
this.Emailphonenumberverification(e.target.value, 1);
};
// 输入页面
loginChange = (e) =>{
var stirngt="";
if(e.target.value.length>0){
var str= e.target.value.replace(/\s*/g,"")
stirngt=str;
}else{
stirngt= e.target.value;
}
if (e.target.value.length === 0) {
this.setState({
loginValue: stirngt,
Phonenumberisnotco:undefined,
})
}else{
this.setState({
loginValue: stirngt,
Phonenumberisnotco:undefined,
})
}
// let reg = /^(\w-*\.*)+@(\w-?)+(\.\w{2,})+$/;
// let reg1 = /^1\d{10}$/;
// let reg2=/^[a-zA-z]\w{3,14}$/;
// // let reg3=/^[a-zA-Z0-9]+([.\-_\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/;
// let value=this.refs.loginPassText.value;
// let valuenum= value.length;
// if(valuenum>0){
// if(!reg.test(value)&&!reg1.test(value)&&!reg2.test(value)){
// this.setState({regular:1})
// return
// }else{
// // this.setState({loginValue:value});
// this.setState({regular:0});
// var stirngt;
// if(value.length>0){
// var str= value.replace(/\s*/g,"")
// stirngt=str;
// }else{
// stirngt= value;
// }
// this.setState({
// loginValue:stirngt,
// });
// }
// }else{
// this.setState({loginValue:value});
// var stirngt;
// if(value.length>0){
// var str= value.replace(/\s*/g,"")
// stirngt=str;
// }else{
// stirngt= value;
// }
// this.setState({
// loginValue:stirngt,
// });
// }
};
//邮箱手机号验证
Emailphonenumberverification = (value, id) => {
var url = `/accounts/valid_email_and_phone.json`;
axios.get((url), {
params: {
login: value,
type: 1,
}
}).then((result) => {
if(result){
if(result.data.status===-2){
if(result.data.message==="该手机号码或邮箱已被注册"){
this.setState({
Phonenumberisnotco: undefined,
Phonenumberisnotcobool: false,
})
}else {
this.setState({
Phonenumberisnotco: result.data.message,
Phonenumberisnotcobool: true,
})
}
return;
}else {
this.setState({
Phonenumberisnotco: undefined,
Phonenumberisnotcobool: false,
})
return;
}
}else{
this.setState({loginValue:value})
}
}
}).catch((error) => {
})
};
passwordChange = () =>{
let value =this.refs.passwordText.value;
@ -411,7 +490,7 @@ class LoginDialog extends Component {
window.location.href = url;
};
render() {
let{open,login,speedy,loginValue,regular,isGoing,isGoingValue,disabled,bottonclass,
let{open,login,speedy,loginValue,regular,isGoing,isGoingValue,disabled,bottonclass,Phonenumberisnotco,
dialogBox,shortcutnum,disabledType,gaincode,authCodeType,authCodeclass, isRender}=this.state;
if (isRender === undefined) {
@ -457,11 +536,13 @@ class LoginDialog extends Component {
id="name_loggin_input"
ref="loginPassText"
onInput={this.loginChange}
onBlur={(e) => this.inputOnBlur(e, 1)}
value={this.state.loginValue}
name="username"
placeholder="请输入有效的手机号/邮箱号" ></input>
<div style={{height: '25px'}}><p className="color-orange edu-txt-left none" id="username_error_notice"
style={{display: regular==0?'none':'block'}}>请输入有效的手机号/邮箱号</p></div>
style={{display: Phonenumberisnotco===undefined?'none':'block'}}>{Phonenumberisnotco}</p></div>
<div>
<input type="password" id="password_loggin_input"

@ -16,7 +16,8 @@ class NewFooter extends Component {
render() {
return (
<div className="newFooter edu-txt-center newContainers">
<div className="newFooter edu-txt-center ">
{/*newContainers*/}
<div className="inner-footer_con">
<div className="footercon">
{/* <div className="inline mt40 mb5">

@ -649,10 +649,22 @@ submittojoinclass=(value)=>{
{...this.state}
{...this.props}
/>:""}
<a href="/" className={" fl"}>
<a href="/" className={"fl mr60 ml25"}>
<img alt="高校智能化教学与实训平台" className="logoimg" src={getImageUrl("images/educoder/headNavLogo.png?1526520218")}></img>
</a>
<div className="educontent">
<style>
{
`
.educontents{
margin: 0px auto;
box-sizing: border-box;
}
`
}
</style>
<div className="educontents fl">
{/*<%= link_to image_tag("/images/educoder/logo.png", alt:"高校智能化教学与实训平台", className:"logoimg"), home_path %>*/}
<div className="head-nav pr">
@ -711,65 +723,67 @@ submittojoinclass=(value)=>{
><a href={this.props.Headertop===undefined?"":this.props.Headertop.auth}>工程认证</a></li>
</ul>
<style>
{
`
</div>
</div>
<style>
{
`
.posi-searchs{
opacity: 1;
position: absolute;
top: -2px;
background: #fff;
z-index: 2;
right: -241px;
opacity: 1;
position: absolute;
top: -2px;
background: #fff;
z-index:10000;
right: 185px;
}
`
}
</style>
<div className="posi-searchs" >
<div className="search-all clearfix">
{/*<!--<a href="javascript:void(0)" className="search-clear fl" onclick="closeSearch();">×</a>-->*/}
<div className="fl pr search-clear edu-menu-panel" style={{display: 'none'}}>
<input type="hidden" id="search_type" value="1"></input>
<span className="searchkey">实训</span>
<i className="fa fa-angle-down ml5 font-16"></i>
<ul id="searchkey" className="edu-menu-list edu-txt-center" style={{minWidth: '80px',right: '-10px',top: '50px'}}>
<li><a>实训</a></li>
<li><a>课堂</a></li>
<li><a>用户</a></li>
</ul>
</div>
{/*<input type="text" className="search-input fl" id="search-input" */}
{/*onKeyDown={this.onKeywordSearchKeyDown} name="search_keyword" placeholder="搜索实训项目"/>*/}
{/*搜索框*/}
{showSearchOpentype===true?<div
className={"HeaderSearch"}
onBlur={(e)=>this.hideshowSearchOpen(e)} onMouseLeave={()=>this.setevaluatinghides()}>
<Search
id={"HeaderSearchs"}
placeholder="实践课程/翻转课堂/开发社区/交流问答"
onInput={()=>this.onKeywordSearchKeyDowns()}
onSearch={(value) => this.onKeywordSearchKeyDown(value)}
// onPressEnter={this.onKeywordSearchKeyDown}
style={{ width: 300,height:32}}
autoFocus={true}
/>
</div>:""}
{/*<a className="search-icon fl" id="header_keyword_search" onClick={this.onKeywordSearch}>*/}
{/*/!*<i className="fa fa-search font-16 mt23 color-grey-6"></i>*!/*/}
{/*<i className="iconfont icon-sousuo color-blue"></i>*/}
{/*</a>*/}
{/* TODO
}
</style>
<div className="posi-searchs" >
<div className="search-all clearfix">
{/*<!--<a href="javascript:void(0)" className="search-clear fl" onclick="closeSearch();">×</a>-->*/}
<div className="fl pr search-clear edu-menu-panel" style={{display: 'none'}}>
<input type="hidden" id="search_type" value="1"></input>
<span className="searchkey">实训</span>
<i className="fa fa-angle-down ml5 font-16"></i>
<ul id="searchkey" className="edu-menu-list edu-txt-center" style={{minWidth: '80px',right: '-10px',top: '50px'}}>
<li><a>实训</a></li>
<li><a>课堂</a></li>
<li><a>用户</a></li>
</ul>
</div>
{/*<input type="text" className="search-input fl" id="search-input" */}
{/*onKeyDown={this.onKeywordSearchKeyDown} name="search_keyword" placeholder="搜索实训项目"/>*/}
{/*搜索框*/}
{showSearchOpentype===true?<div
className={"HeaderSearch"}
onBlur={(e)=>this.hideshowSearchOpen(e)} onMouseLeave={()=>this.setevaluatinghides()}>
<Search
id={"HeaderSearchs"}
placeholder="实践课程/翻转课堂/开发社区/交流问答"
onInput={()=>this.onKeywordSearchKeyDowns()}
onSearch={(value) => this.onKeywordSearchKeyDown(value)}
// onPressEnter={this.onKeywordSearchKeyDown}
style={{ width: 300,height:32}}
autoFocus={true}
/>
</div>:""}
{/*<a className="search-icon fl" id="header_keyword_search" onClick={this.onKeywordSearch}>*/}
{/*/!*<i className="fa fa-search font-16 mt23 color-grey-6"></i>*!/*/}
{/*<i className="iconfont icon-sousuo color-blue"></i>*/}
{/*</a>*/}
{/* TODO
<div className="search-content none" style="width: 86%;left: 0px;">
<div className="search-title">最近搜索</div>
<div><a href="javascript:void(0)" className="search_history">绿盟</a></div>
<div><a href="javascript:void(0)" className="search_history">qwe</a></div>
</div>*/}
</div>
</div>
</div>
</div>
</div>
{/*<span className="font-15 fr mt17">
<%= link_to '登录', signin_path, :className => "mr5" %>
@ -777,16 +791,16 @@ submittojoinclass=(value)=>{
<%= link_to '注册', user_join_path, :className => "ml5" %>
</span>*/}
{ user===undefined?
<span className="font-15 fr mt17 ml20">
<span className="font-15 fr mt17 ml10 mr25">
<a onClick={()=>this.educoderlogin()} className="mr5 color-white">登录</a>
<em className="vertical-line"></em>
<a href={"/register"} className="mr5 color-white">注册</a>
</span> :user.login===""?<span className="font-15 fr mt17 ml20">
</span> :user.login===""?<span className="font-15 fr mt17 ml20 mr25">
<a onClick={()=>this.educoderlogin()} className="mr5 color-white">登录</a>
<em className="vertical-line"></em>
<a href={"/register"} className="mr5 color-white">注册</a>
</span>:
<div className="fr edu-menu-panel" style={{height:'60px'}}>
<div className="fr edu-menu-panel mr25" style={{height:'60px'}}>
<a href={`/users/${this.props.current_user===undefined?"":this.props.current_user.login}/courses`} className="fl ml15">
<img alt="头像" className="radius mt13" height="34" id="nh_user_logo" name="avatar_image"
src={getImageUrl(`images/`+user.image_url)} width="34">
@ -814,7 +828,7 @@ submittojoinclass=(value)=>{
</div>
}
{/*href="https://www.educoder.net/login"*/}
<div className="fr head-right ">
<div className="fr head-right">
{/*{ loadHeader()}*/}
{showSearchOpentype===true?"":<a id="search-open" className="fl mr30 headIcon" onClick={(e)=>this.showSearchOpen(e)}>
{/*"/images/educoder/icon/search.svg"
@ -852,7 +866,7 @@ submittojoinclass=(value)=>{
{/* /courses/join_course_multi_role */}
{/*<li>*/}
{/* <a onClick={this.tojoinitem}>加入项目</a>*/}
<a onClick={this.tojoinitem}>加入项目</a>
{/*</li>*/}
<Modal
keyboard={false}
@ -949,7 +963,7 @@ submittojoinclass=(value)=>{
</Modal>
</div>
</div>
</div>
);

@ -201,3 +201,11 @@ body>.-task-title {
.HeaderSearch{
width: 325px;
}
.mainheighs{
height: 100%;
display: block;
}
.ml18a{
margin-left:18%;
}

@ -20,7 +20,7 @@ const versionNum = '0001';
// let _url_origin = getUrl()
let _url_origin='';
if(window.location.port === "3007"){
_url_origin="https://newweb.educoder.net";
_url_origin="http://47.96.87.25:48080/";
}
// let _url_origin=`https://www.educoder.net`;

@ -556,7 +556,7 @@ class LoginRegisterComponent extends Component {
}).catch((error) => {
})
}
};
//短信验证
SMSverification = () => {
var url = `/accounts/get_verification_code.json`;
@ -689,60 +689,6 @@ class LoginRegisterComponent extends Component {
}
//失去焦点判断
inputOnBlur = (e, id) => {
// this.isCorrectname(e.target.value, id);
// this.Emailphonenumberverification(e.target.value, id);
if (e.target.value.length === 0) {
this.setState({
Phonenumberisnotco: undefined,
Phonenumberisnotcobool: false,
})
return;
}
// var telephone = $("#telephoneAdd.tianjia_phone").val();
var regph = /^[1][3,4,5,6,7,8][0-9]{9}$/;
// var email = $("#add_email.tianjia_email").val();
var regemail = /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/;
// [1]手机号开头必须是1 [3,4,5,6,7,8] 第二位是3-8中的一个 [0-9]{9} 后边9位可以是0-9的任意数字。
var stringdata = undefined;
if (!regph.test(e.target.value)) {
stringdata = "手机号格式不正确";
this.setState({
Phonenumberisnotco: stringdata,
Phonenumberisnotcobool: true,
dragOk:false,
Whethertoverify:this.state.Whethertoverify===true?false:true,
})
} else {
this.setState({
Phonenumberisnotco: undefined,
Phonenumberisnotcobool: false,
})
return
}
if (!regemail.test(e.target.value)) {
if ((e.target.value.indexOf("@") != -1) === true) {
stringdata = "邮箱格式不正确";
} else {
stringdata = "手机号格式不正确";
}
this.setState({
Phonenumberisnotco: stringdata,
Phonenumberisnotcobool: true,
dragOk:false,
Whethertoverify:this.state.Whethertoverify===true?false:true,
})
return
} else {
this.setState({
Phonenumberisnotco: undefined,
Phonenumberisnotcobool: false,
})
this.Emailphonenumberverification(e.target.value, 1);
return
}
this.Emailphonenumberverification(e.target.value, 1);
}
inputOnBlurzhuche = (e, id) => {

@ -37,6 +37,12 @@ class Notcompletedysl extends Component {
if(weekArray===undefined){
weekArray="/";
}
if(weekArray===null){
weekArray="/";
}
if(weekArray==="null"){
weekArray="/";
}
window.location.href = weekArray;
}
@ -46,7 +52,7 @@ class Notcompletedysl extends Component {
render() {
console.log(this.props)
// console.log(this.props)
return(
<Modal
keyboard={false}

@ -151,7 +151,7 @@ class ChangeHeaderPicModal extends Component{
text-align: center;
width: 120px;
height: 120px;
border: 1px solid #eee;
/* border: 1px solid #eee; */
}
.previewWrap {
flex-direction: column;

@ -130,7 +130,7 @@ class InfosCourse extends Component{
this.props.current_user && this.props.current_user.user_identity != "学生" ? <Create href={"/courses/new"} name={"新建课堂"} index="1"></Create> : ""
}
{
(!data || data.courses.length==0) && (this.props.current_user && this.props.current_user.user_identity === "学生" ) && <NoneData></NoneData>
(!data || data.courses.length==0) && (!is_current || (this.props.current_user && this.props.current_user.user_identity === "学生" )) && <NoneData></NoneData>
}
{
data && data.courses && data.courses.map((item,key)=>{
@ -147,7 +147,7 @@ class InfosCourse extends Component{
{
item.can_visited ==false?
<div className="closeSquare">
<img src={getImageUrl("/images/educoder/icon/lockclose.svg")} className="mt80 mb25"/>
<img src={getImageUrl("images/educoder/icon/lockclose.svg")} className="mt80 mb25"/>
<p className="font-14 color-white">非成员不能访问</p>
</div>:""
}

@ -152,7 +152,7 @@ class InfosPath extends Component{
this.props.current_user && this.props.current_user.user_identity != "学生" ? <Create href={"/paths/new"} name={"新建实践课程"} index="3"></Create>:""
}
{
(!data || data.subjects.length==0) && (this.props.current_user && this.props.current_user.user_identity === "学生" ) && <NoneData></NoneData>
(!data || data.subjects.length==0) && (!is_current || (this.props.current_user && this.props.current_user.user_identity === "学生" )) && <NoneData></NoneData>
}
{
data && data.subjects && data.subjects.map((item,key)=>{

@ -125,7 +125,7 @@ class InfosProject extends Component{
<Create href={`${this.props.Headertop && this.props.Headertop.old_url}/projects/new`} name={"新建项目"} index="4"></Create>:""
}
{
(!data || data.projects.length==0) && (this.props.current_user && this.props.current_user.user_identity === "学生" ) && <NoneData></NoneData>
(!data || data.projects.length==0) && (!is_current || (this.props.current_user && this.props.current_user.user_identity === "学生" )) && <NoneData></NoneData>
}
{
data && data.projects && data.projects.map((item,key)=>{
@ -142,7 +142,7 @@ class InfosProject extends Component{
{
item.can_visited ==false?
<div className="closeSquare">
<img src={getImageUrl("/images/educoder/icon/lockclose.svg")} className="mt80 mb25"/>
<img src={getImageUrl("images/educoder/icon/lockclose.svg")} className="mt80 mb25"/>
<p className="font-14 color-white">非成员不能访问</p>
</div>:""
}

@ -161,7 +161,7 @@ class InfosShixun extends Component{
<Create href={"/shixuns/new"} name={"新建实训"} index="2"></Create>:""
}
{
(!data || data.shixuns.length==0) && (this.props.current_user && this.props.current_user.user_identity === "学生" ) && <NoneData></NoneData>
(!data || data.shixuns.length==0) && (!is_current || (this.props.current_user && this.props.current_user.user_identity === "学生" )) && <NoneData></NoneData>
}
{
data && data.shixuns && data.shixuns.map((item,key)=>{

@ -164,7 +164,7 @@ class SearchPage extends Component{
<div className="mh650 bjyss">
<div className="edu-tab-con-box clearfix edu-txt-center">
<img className="edu-nodata-img mb20" src={getImageUrl("images/educoder/nodata.png")}/>
<p className="edu-nodata-p mb30">没有数据可以显示</p>
<p className="edu-nodata-p mb30">暂时还没有相关数据哦</p>
</div>
</div>

@ -1,11 +1,25 @@
/*--------------------------首页*/
/*头部导航条样式---2018-03-19--by-cs*/
.newHeader{background: #24292D !important; width:100%; height: 60px !important; min-width: 1200px;position: fixed;top: 0px;left: 0px;z-index:1000;-moz-box-shadow: 0px 0px 12px rgba(0,0,0,0.1); /* 老的 Firefox */box-shadow: 0px 0px 12px rgba(0,0,0,0.1);}
.newHeader{
/*overflow:hidden;*/
/*text-overflow:ellipsis;*/
/*white-space:nowrap;*/
background: #24292D !important; width:100%; height: 60px !important; min-width: 1200px;position: fixed;top: 0px;left: 0px;z-index:1000;-moz-box-shadow: 0px 0px 12px rgba(0,0,0,0.1); /* 老的 Firefox */box-shadow: 0px 0px 12px rgba(0,0,0,0.1);
}
.newHeader .logoimg{
margin-top: 16px;
float: left;
width: 97px;}
.head-nav{float: left;width:830px;text-align: center;height: 60px;box-sizing: border-box; min-width: 400px;}
.head-nav{
float: left;
text-align: center;
height: 60px;
box-sizing: border-box;
min-width: 785px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.head-nav ul#header-nav{position: absolute;top: 0px;z-index: 3;height: 60px;box-sizing: border-box;}
.head-nav ul#header-nav li{float: left;height: 60px;line-height: 60px;margin-right: 30px;cursor: pointer;position: relative;font-size: 16px}
.head-nav ul#header-nav li a{display: block;height: 100%;width: 100%;color: #fff}

Loading…
Cancel
Save