diff --git a/app/controllers/admins/mirror_repositories_controller.rb b/app/controllers/admins/mirror_repositories_controller.rb index aed8dc09e..63e4667d1 100644 --- a/app/controllers/admins/mirror_repositories_controller.rb +++ b/app/controllers/admins/mirror_repositories_controller.rb @@ -87,7 +87,6 @@ class Admins::MirrorRepositoriesController < Admins::BaseController end def check_shixun_mirrors! - return return unless request.format.html? Admins::CheckShixunMirrorsService.call diff --git a/app/controllers/admins/shixun_settings_controller.rb b/app/controllers/admins/shixun_settings_controller.rb index 9919c7daa..d635ae8df 100644 --- a/app/controllers/admins/shixun_settings_controller.rb +++ b/app/controllers/admins/shixun_settings_controller.rb @@ -1,8 +1,7 @@ class Admins::ShixunSettingsController < Admins::BaseController def index - params[:sort_by] = params[:sort_by].presence || 'created_on' - params[:sort_direction] = params[:sort_direction].presence || 'desc' + default_sort('created_at', 'desc') shixun_settings = Admins::ShixunSettingsQuery.call(params) @editing_shixuns = shixun_settings.where(status:0).size diff --git a/app/controllers/exercises_controller.rb b/app/controllers/exercises_controller.rb index a6464a151..784bb9c9a 100644 --- a/app/controllers/exercises_controller.rb +++ b/app/controllers/exercises_controller.rb @@ -1084,14 +1084,23 @@ class ExercisesController < ApplicationController @shixun_undo = 0 @ques_undo = 0 ex_answer_time = @exercise.time.to_i - @ex_end_time = @exercise.get_exercise_end_time(current_user.id) - if ex_answer_time > 0 - exercise_end_time = @exercise.exercise_users.exercise_commit_users(current_user.id) - if exercise_end_time.present? - ex_end_times = exercise_end_time.first.start_at.nil? ? Time.now : exercise_end_time.first.start_at - @ex_end_time = ex_end_times + ex_answer_time.minutes - end + if ex_answer_time > 0 #有剩余时间的时候 + user_left_time = get_exercise_left_time(@exercise,current_user) + @ex_end_time = Time.now + user_left_time.to_i.seconds + else + @ex_end_time = @exercise.get_exercise_end_time(current_user.id) end + # @ex_end_time = @exercise.get_exercise_end_time(current_user.id) + # if ex_answer_time > 0 + # left_answer_time = Time.now + ex_answer_time.minutes #判断试卷的倒计时和截止时间哪个先到 + # if left_answer_time < @ex_end_time + # exercise_end_time = @exercise.exercise_users.exercise_commit_users(current_user.id) + # if exercise_end_time.present? + # ex_end_times = exercise_end_time.first.start_at.nil? ? Time.now : exercise_end_time.first.start_at + # @ex_end_time = ex_end_times + ex_answer_time.minutes + # end + # end + # end @exercise_questions.each do |q| if q.question_type == Exercise::PRACTICAL #当为实训题时 user_myshixun = q.shixun.myshixuns.search_myshixun_user(current_user.id) diff --git a/app/controllers/games_controller.rb b/app/controllers/games_controller.rb index 78f665b3d..1457cafcc 100644 --- a/app/controllers/games_controller.rb +++ b/app/controllers/games_controller.rb @@ -290,6 +290,7 @@ class GamesController < ApplicationController answer_deduction = challenge.challenge_answers.where("level <= #{@answer.level}").sum(:score) @game.update_attributes!(:answer_open => answer_open, :answer_deduction => answer_deduction) end + GameAnswer.create!(challenge_answer_id: @answer.id, user_id: current_user.id, game_id: @game.id, view_time: Time.now) rescue Exception => e uid_logger_error("#######金币扣除异常: #{e.message}") @@ -317,6 +318,7 @@ class GamesController < ApplicationController @game.update_attributes!(:answer_open => 1, :answer_deduction => 100) end @challenge_chooses = @challenge.challenge_chooses + GameAnswer.create!(user_id: current_user.id, game_id: @game.id, view_time: Time.now) rescue Exception => e uid_logger_error("#######金币扣除异常: #{e.message}") raise ActiveRecord::Rollback diff --git a/app/controllers/oauth/base_controller.rb b/app/controllers/oauth/base_controller.rb index e2eb26a2a..e4068fbda 100644 --- a/app/controllers/oauth/base_controller.rb +++ b/app/controllers/oauth/base_controller.rb @@ -1,9 +1,14 @@ class Oauth::BaseController < ActionController::Base include RenderHelper include LoginHelper + include ControllerRescueHandler skip_before_action :verify_authenticity_token + def auth_failure + render_error(params[:message]) + end + private def session_user_id @@ -15,6 +20,7 @@ class Oauth::BaseController < ActionController::Base end def auth_hash + Rails.logger.info("[OAuth2] omniauth.auth -> #{request.env['omniauth.auth'].inspect}") request.env['omniauth.auth'] end end \ No newline at end of file diff --git a/app/controllers/subjects_controller.rb b/app/controllers/subjects_controller.rb index b7b208842..cbedf74b2 100644 --- a/app/controllers/subjects_controller.rb +++ b/app/controllers/subjects_controller.rb @@ -5,7 +5,7 @@ class SubjectsController < ApplicationController before_action :find_subject, except: [:index, :create, :new, :append_to_stage] before_action :allowed, only: [:update, :edit, :destroy, :publish, :cancel_publish, :cancel_has_publish, :search_members, :add_subject_members, :statistics, :shixun_report, :school_report, - :up_member_position, :down_member_position] + :up_member_position, :down_member_position, :update_team_title] include ApplicationHelper include SubjectsHelper @@ -264,6 +264,12 @@ class SubjectsController < ApplicationController end end + def update_team_title + tip_exception("team_title参数不能为空") if params[:team_title].blank? + @subject.update_attributes!(team_title: params[:team_title]) + normal_status("更新成功") + end + def search_members tip_exception("搜索内容不能为空") unless params[:search] page = params[:page] || 1 diff --git a/app/helpers/exercises_helper.rb b/app/helpers/exercises_helper.rb index 395d67913..323bad3cf 100644 --- a/app/helpers/exercises_helper.rb +++ b/app/helpers/exercises_helper.rb @@ -142,6 +142,9 @@ module ExercisesHelper right_users_count = 0 #该问题的正确率 if ex.question_type == Exercise::MULTIPLE #多选题 + if standard_answer.size == 1 #以前的多选题答案存在一个表里 + standard_answer = standard_answer.first.to_s.split("").map(&:to_i) + end right_user_ids = user_ids standard_answer.each do |choice_position| standard_answer_choice_id = ex_choices.select{|ec| ec.choice_position == choice_position}.first&.id @@ -896,7 +899,8 @@ module ExercisesHelper if ex_time > 0 exercise_user = exercise.exercise_users.find_by(user_id:user.id) time_mill = ex_time * 60 #转为秒 - exercise_end_time = exercise.end_time.present? ? exercise.end_time.to_i : 0 + exercise_end_time = exercise.get_exercise_end_time(user.id) #没有考虑分班的情况 + # exercise_end_time = exercise.end_time.present? ? exercise.end_time.to_i : 0 exercise_user_start = exercise_user&.start_at.present? ? exercise_user.start_at.to_i : 0 #用户未开始答题时,即exercise_user_start为0 if exercise_user_start == 0 diff --git a/app/helpers/myshixuns_helper.rb b/app/helpers/myshixuns_helper.rb index 2a487e361..e643555e1 100644 --- a/app/helpers/myshixuns_helper.rb +++ b/app/helpers/myshixuns_helper.rb @@ -11,4 +11,8 @@ module MyshixunsHelper nil end end + + def view_answer_time game, user_id + game.game_answers.where(user_id: user_id).last&.view_time + end end diff --git a/app/libs/omniauth/strategies/qq.rb b/app/libs/omniauth/strategies/qq.rb index 513257e3c..97cd9de94 100644 --- a/app/libs/omniauth/strategies/qq.rb +++ b/app/libs/omniauth/strategies/qq.rb @@ -6,6 +6,7 @@ module OmniAuth authorize_url: '/oauth2.0/authorize', token_url: '/oauth2.0/token' } + option :token_params, { parse: :query } def request_phase super @@ -21,7 +22,17 @@ module OmniAuth end end - uid { raw_info['openid'].to_s } + uid do + @uid ||= begin + access_token.options[:mode] = :query + access_token.options[:param_name] = :access_token + # Response Example: "callback( {\"client_id\":\"11111\",\"openid\":\"000000FFFF\"} );\n" + response = access_token.get('/oauth2.0/me') + + matched = response.body.match(/"openid":"(?\w+)"/) + matched[:openid] + end + end info do { @@ -35,15 +46,10 @@ module OmniAuth { raw_info: user_info } end - def raw_info - access_token.options[:mode] = :query - @raw_info ||= access_token.get('/oauth2.0/me').parsed - end - def user_info access_token.options[:mode] = :query - params = { oauth_consumer_key: options.client_id, openid: raw_info['openid'], format: 'json' } - @user_info ||= access_token.get('/user/get_user_info', params: params) + param = { oauth_consumer_key: options[:client_id], openid: uid, format: 'json' } + @user_info ||= access_token.get('/user/get_user_info', params: param, parse: :json).parsed end end end diff --git a/app/models/challenge_answer.rb b/app/models/challenge_answer.rb index 93b11be66..0ce757d71 100644 --- a/app/models/challenge_answer.rb +++ b/app/models/challenge_answer.rb @@ -1,4 +1,9 @@ class ChallengeAnswer < ApplicationRecord default_scope { order("challenge_answers.level asc") } belongs_to :challenge + has_many :game_answers, :dependent => :destroy + + def view_answer_time(user_id) + game_answers.where(user_id: user_id).last&.view_time + end end diff --git a/app/models/game.rb b/app/models/game.rb index d7c68dd5f..7aa2e7264 100644 --- a/app/models/game.rb +++ b/app/models/game.rb @@ -15,7 +15,7 @@ class Game < ApplicationRecord belongs_to :user belongs_to :challenge has_one :run_code_message, :dependent => :destroy - + has_many :game_answers, :dependent => :destroy #全部关卡数 scope :ch_games, lambda { |challenge_id| where(challenge_id:challenge_id) } diff --git a/app/models/game_answer.rb b/app/models/game_answer.rb new file mode 100644 index 000000000..c355b0a6c --- /dev/null +++ b/app/models/game_answer.rb @@ -0,0 +1,5 @@ +class GameAnswer < ApplicationRecord + belongs_to :user + belongs_to :game + belongs_to :challenge_answer +end diff --git a/app/services/admins/check_shixun_mirrors_service.rb b/app/services/admins/check_shixun_mirrors_service.rb index 868fab042..8334df485 100644 --- a/app/services/admins/check_shixun_mirrors_service.rb +++ b/app/services/admins/check_shixun_mirrors_service.rb @@ -77,10 +77,11 @@ class Admins::CheckShixunMirrorsService < ApplicationService @_bridge_images ||= begin url = EduSetting.get('cloud_bridge') res = Faraday.get(url) + res_body = JSON.parse(res.body) - raise Error, '拉取镜像信息异常' if res && res['code'].nonzero? + raise Error, '拉取镜像信息异常' if res_body && res_body['code'].to_i != 0 - res + res_body rescue => e Rails.logger.error("get response failed ! #{e.message}") raise Error, '实训云平台繁忙(繁忙等级:84)' diff --git a/app/services/oauth/create_or_find_qq_account_service.rb b/app/services/oauth/create_or_find_qq_account_service.rb index c258993bd..92966634c 100644 --- a/app/services/oauth/create_or_find_qq_account_service.rb +++ b/app/services/oauth/create_or_find_qq_account_service.rb @@ -28,7 +28,7 @@ class Oauth::CreateOrFindQqAccountService < ApplicationService user.create_user_extension!(gender: gender) # 下载头像 avatar_path = Util::FileManage.source_disk_filename(user) - Util.download_file(params.dig('info', 'figureurl_qq_1'), avatar_path) + Util.download_file(params.dig('info', 'image'), avatar_path) end new_open_user = OpenUsers::QQ.create!(user: user, uid: params['uid'], extra: params.dig('extra', 'raw_info')) diff --git a/app/templates/shixun_work/shixun_work.html.erb b/app/templates/shixun_work/shixun_work.html.erb index a6ef48c3e..c4ea11f1e 100644 --- a/app/templates/shixun_work/shixun_work.html.erb +++ b/app/templates/shixun_work/shixun_work.html.erb @@ -249,6 +249,7 @@ autoRefresh: true, smartIndent: true,//智能换行 styleActiveLine: true, + lineWrapping: true, lint: true, readOnly: "nocursor" }); diff --git a/app/views/admins/competition_prize_users/shared/_tr.html.erb b/app/views/admins/competition_prize_users/shared/_tr.html.erb index 18912c36a..66d0b64ad 100644 --- a/app/views/admins/competition_prize_users/shared/_tr.html.erb +++ b/app/views/admins/competition_prize_users/shared/_tr.html.erb @@ -16,7 +16,7 @@ <% if prize_user.leader? && prize_user.competition_prize.category == 'bonus' %> <% bank_content = [prize_user.extra&.[]('bank'), prize_user.extra&.[]('second_bank'), prize_user.extra&.[]('card_no')].compact.join('
').presence || '无' %> - <%= javascript_void_link('查看银行账户', data: { toggle: 'popover', title: '银行账号', content: bank_content.html_safe, html: true }) %> + <%= javascript_void_link('查看银行账户', data: { toggle: 'tooltip', title: bank_content.html_safe, html: true, placement: 'left', trigger: 'click' }) %> <% end %> <% if prize_user.pending? %> diff --git a/app/views/competitions/prizes/show.json.jbuilder b/app/views/competitions/prizes/show.json.jbuilder index c97ff6fbe..9bb6b8256 100644 --- a/app/views/competitions/prizes/show.json.jbuilder +++ b/app/views/competitions/prizes/show.json.jbuilder @@ -5,6 +5,7 @@ if @leader json.bank_account_editable @bank_account_editable end +json.all_certified current_user.all_certified? json.personal_certifications do json.array! @self_prizes do |prize_user| json.url personal_competition_certificate_path(current_competition.identifier, prize_user) diff --git a/app/views/games/get_answer_info.json.jbuilder b/app/views/games/get_answer_info.json.jbuilder index 0f150d500..29d88933c 100644 --- a/app/views/games/get_answer_info.json.jbuilder +++ b/app/views/games/get_answer_info.json.jbuilder @@ -7,6 +7,7 @@ json.message do json.answer_id answer.id json.answer_name answer.name json.answer_score answer.score + json.view_time answer.view_answer_time(current_user.id) # 高层级不给答案 if @power || @game.answer_open >= index json.answer_contents answer.contents diff --git a/app/views/myshixuns/challenges.json.jbuilder b/app/views/myshixuns/challenges.json.jbuilder index 0be94d9fd..e16896451 100644 --- a/app/views/myshixuns/challenges.json.jbuilder +++ b/app/views/myshixuns/challenges.json.jbuilder @@ -6,4 +6,6 @@ json.array! @games do |game| json.identifier get_game_identifier(@shixun.task_pass, game, @identity) json.get_gold game.user_get_gold_and_experience(@shixun.status, challenge)[0] json.get_experience game.user_get_gold_and_experience(@shixun.status, challenge)[1] + json.view_answer_time view_answer_time(game, current_user.id) + json.finished_time game.end_time end \ No newline at end of file diff --git a/app/views/subjects/right_banner.json.jbuilder b/app/views/subjects/right_banner.json.jbuilder index da8161a98..ef5645f26 100644 --- a/app/views/subjects/right_banner.json.jbuilder +++ b/app/views/subjects/right_banner.json.jbuilder @@ -5,6 +5,8 @@ json.members @members do |member| json.role member.role end +json.team_title @subject.team_title + # 技能标签 json.tags @tags do |tag| unless tag.blank? diff --git a/app/views/subjects/show.json.jbuilder b/app/views/subjects/show.json.jbuilder index 7febcd789..870d33d40 100644 --- a/app/views/subjects/show.json.jbuilder +++ b/app/views/subjects/show.json.jbuilder @@ -12,6 +12,7 @@ json.allow_send @user.logged? json.allow_visit @subject.status > 1 || @is_manager json.allow_add_member @is_manager json.is_creator @is_creator +json.cover url_to_avatar(@subject) if @subject.excellent json.has_start @subject.has_course_start? diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb index 27ade9ed4..3eed48c20 100644 --- a/config/initializers/omniauth.rb +++ b/config/initializers/omniauth.rb @@ -1,4 +1,8 @@ OmniAuth.config.add_camelization 'qq', 'QQ' +OmniAuth.config.logger = Rails.logger +OmniAuth.config.on_failure = Proc.new { |env| + OmniAuth::FailureEndpoint.new(env).redirect_to_failure +} oauth_config = {} begin @@ -13,5 +17,5 @@ rescue => ex end Rails.application.config.middleware.use OmniAuth::Builder do - provider :qq, oauth_config['appid'], oauth_config['secret'] + provider :qq, oauth_config['appid'], oauth_config['secret'], { provider_ignores_state: true } end diff --git a/config/routes.rb b/config/routes.rb index 3cf18fe75..796d1d989 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -6,6 +6,8 @@ Rails.application.routes.draw do get 'attachments/download/:id', to: 'attachments#show' get 'attachments/download/:id/:filename', to: 'attachments#show' + get 'auth/qq/callback', to: 'oauth/qq#create' + get 'auth/failure', to: 'oauth/base#auth_failure' resources :edu_settings scope '/api' do @@ -289,6 +291,7 @@ Rails.application.routes.draw do post :down_member_position get :right_banner post :appointment + post :update_team_title end collection do diff --git a/db/migrate/20191104033349_create_game_answers.rb b/db/migrate/20191104033349_create_game_answers.rb new file mode 100644 index 000000000..211a0c29d --- /dev/null +++ b/db/migrate/20191104033349_create_game_answers.rb @@ -0,0 +1,13 @@ +class CreateGameAnswers < ActiveRecord::Migration[5.2] + def change + create_table :game_answers do |t| + t.references :challenge_answer + t.references :user + t.references :game + t.datetime :view_time + + t.timestamps + end + + end +end diff --git a/db/migrate/20191104055038_add_index_for_game_answers.rb b/db/migrate/20191104055038_add_index_for_game_answers.rb new file mode 100644 index 000000000..7cd59c6ee --- /dev/null +++ b/db/migrate/20191104055038_add_index_for_game_answers.rb @@ -0,0 +1,5 @@ +class AddIndexForGameAnswers < ActiveRecord::Migration[5.2] + def change + add_index :game_answers, [:challenge_answer_id, :user_id], :unique => true + end +end diff --git a/db/migrate/20191104063136_add_team_title_to_subjects.rb b/db/migrate/20191104063136_add_team_title_to_subjects.rb new file mode 100644 index 000000000..d515a800a --- /dev/null +++ b/db/migrate/20191104063136_add_team_title_to_subjects.rb @@ -0,0 +1,5 @@ +class AddTeamTitleToSubjects < ActiveRecord::Migration[5.2] + def change + add_column :subjects, :team_title, :string, default: "教学团队" + end +end diff --git a/public/editormd/lib/marked.min.js b/public/editormd/lib/marked.min.js index bfcb191af..eb14b2545 100644 --- a/public/editormd/lib/marked.min.js +++ b/public/editormd/lib/marked.min.js @@ -10,8 +10,9 @@ out+=this.renderer.em(this.output(cap[2]||cap[1])) --> out+=this.renderer.em(this.output(cap[2]||cap[1]), cap.input) */ -// 0.4.0 /^ *(#{1,6}) ——》/^ *(#{1,6}) 去掉了一个空格 TODO 行内公式带_ +// 0.4.0 /^ *(#{1,6}) ——》/^ *(#{1,6}) 去掉了一个空格 /*if("string"!=typeof e)throw new Error("marked(): input parameter is of type "+Object.prototype.toString.call(e)+", string expected");*/ +// 说明:左边 --> 右边 左边被替换成了右边的内容 // b(i[1].replace(/^ *| *\| *$/g,"")) --> i[1].replace(/^ *| *\| *$/g, "").split(/ *\| */) table没识别的问题 // header.length===a.align.length --> header.length table没识别的问题 // 2个table: b(a.cells[p],a.header.length) -> a.cells[p].replace(/^ *\| *| *\| *$/g, "").split(/ *\| */) diff --git a/public/react/config/webpack.config.dev.js b/public/react/config/webpack.config.dev.js index f335f1705..743b3685c 100644 --- a/public/react/config/webpack.config.dev.js +++ b/public/react/config/webpack.config.dev.js @@ -32,7 +32,7 @@ module.exports = { // See the discussion in https://github.com/facebookincubator/create-react-app/issues/343.s // devtool: "cheap-module-eval-source-map", // 开启调试 - devtool: "source-map", // 开启调试 + // devtool: "source-map", // 开启调试 // These are the "entry points" to our application. // This means they will be the "root" imports that are included in JS bundle. // The first two entry points enable "hot" CSS and auto-refreshes for JS. diff --git a/public/react/public/css/demo_index.html b/public/react/public/css/demo_index.html index 8a75ddb27..c88449b3f 100644 --- a/public/react/public/css/demo_index.html +++ b/public/react/public/css/demo_index.html @@ -222,6 +222,12 @@
&#xe693;
+
  • + +
    关注
    +
    &#xe6c0;
    +
  • +
  • 礼物
    @@ -324,6 +330,12 @@
    &#xe678;
  • +
  • + +
    关注
    +
    &#xe6c5;
    +
  • +
  • 喇叭
    @@ -1718,6 +1730,15 @@
  • +
  • + +
    + 关注 +
    +
    .icon-weibiaoti105 +
    +
  • +
  • @@ -1871,6 +1892,15 @@
  • +
  • + +
    + 关注 +
    +
    .icon-guanzhu +
    +
  • +
  • @@ -3740,6 +3770,14 @@
    #icon-renzhengxinxi
  • +
  • + +
    关注
    +
    #icon-weibiaoti105
    +
  • +
  • #icon-dashujucunchu
  • +
  • + +
    关注
    +
    #icon-guanzhu
    +
  • +
  • 暂未生成 原因:还未认证个人信息,this.props.Competitioncallback("2")}>立即查看: + 个人证书:{data&&data.personal_certifications.length===0&&data&&data.all_certified===false? + 暂未生成 原因:还未认证个人信息,this.props.Competitioncallback("2")}>立即认证: + data&&data.personal_certifications.length===0&&data&&data.all_certified===true? + 暂未生成 原因:组委会未完成证书审批,请稍后: data&&data.personal_certifications.map((item,key)=>{ return( diff --git a/public/react/src/modules/courses/busyWork/CommonWorkList.js b/public/react/src/modules/courses/busyWork/CommonWorkList.js index 772187078..e5046a9d5 100644 --- a/public/react/src/modules/courses/busyWork/CommonWorkList.js +++ b/public/react/src/modules/courses/busyWork/CommonWorkList.js @@ -369,7 +369,9 @@ function buildColumns(that, student_works, studentData) { } {/* toWorkDetailPage */} {/* /courses/"+courseId+"/common_homeworks/"+workId+ '/' + record.id +"/appraise */} - that.props.toWorkDetailPage(courseId, workId, record.id)} >{ isAdmin ? '评阅': '查看'} + that.props.toWorkDetailPage2(e, courseId, workId, record.id)} + onClick={() => that.props.toWorkDetailPage(courseId, workId, record.id)}>{isAdmin ? '评阅' : '查看'} diff --git a/public/react/src/modules/courses/busyWork/common.js b/public/react/src/modules/courses/busyWork/common.js index b1828997b..f8327adcd 100644 --- a/public/react/src/modules/courses/busyWork/common.js +++ b/public/react/src/modules/courses/busyWork/common.js @@ -12,15 +12,15 @@ export function RouteHOC(options = {}) { return class Wrapper extends Component { constructor(props) { super(props); - + this.state = { - + } } toCreateProject = () => { let url = '/projects/new' if (window.location.port == 3007) { - // window.location.href + // window.location.href url = '/testbdweb.educoder.net/projects/new' } window.open( @@ -55,8 +55,8 @@ export function RouteHOC(options = {}) { } else { this.props.history.push(`/courses/${_courseId}/boards/${workId}/messages/${topicId}`) } - - } + + } toEditPage = (_courseId, _workId) => { const secondName = this.getModuleName() if (typeof _courseId == "object") { @@ -78,6 +78,19 @@ export function RouteHOC(options = {}) { window.open(`/courses/${_courseId}/${secondName}/${_workId}/${_studentWorkId}/appraise`); } } + toWorkDetailPage2 = (e, _courseId, _workId, _studentWorkId) => { + console.log("鼠标中键点击了") + console.log(_studentWorkId) + const secondName = this.getModuleName() + if (typeof _courseId == "object") { + const workId = _courseId.workId + const courseId = _courseId.coursesId + const studentWorkId = _courseId.studentWorkId + window.open(`/courses/${courseId}/${secondName}/${_workId || workId}/${_studentWorkId || studentWorkId}/appraise`); + } else { + window.open(`/courses/${_courseId}/${secondName}/${_workId}/${_studentWorkId}/appraise`); + } + } toNewPage = (courseId) => { const secondName = this.getModuleName() this.props.history.push(`/courses/${courseId.coursesId}/${secondName}/${courseId.category_id}/new`) @@ -125,8 +138,8 @@ export function RouteHOC(options = {}) { this.props.history.push(`/courses/${_courseId}/${secondName}/${_workId}/answer`) } } - - toWorkQuestionPage = (_courseId, _workId) => { + + toWorkQuestionPage = (_courseId, _workId) => { const secondName = this.getModuleName() if (typeof _courseId == "object") { const workId = _workId || _courseId.workId @@ -148,37 +161,36 @@ export function RouteHOC(options = {}) { } } - - render() { + render() { const { snackbarOpen} = this.state; return ( - - - + + ) } } } -} \ No newline at end of file +} diff --git a/public/react/src/modules/courses/exercise/new/SingleEditor.js b/public/react/src/modules/courses/exercise/new/SingleEditor.js index 1e2005360..f3c917c75 100644 --- a/public/react/src/modules/courses/exercise/new/SingleEditor.js +++ b/public/react/src/modules/courses/exercise/new/SingleEditor.js @@ -16,8 +16,8 @@ const $ = window.$ const { Option } = Select; const tagArray = [ - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', - 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', + 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' ] class SingleEditor extends Component{ @@ -92,13 +92,13 @@ class SingleEditor extends Component{ } - + const intScore = parseFloat(question_score) if (intScore == 0) { this.props.showNotification('分值:必须大于0'); return; } else if(!question_score || intScore == NaN) { this.props.showNotification('分值:不能为空'); return; - } + } if(!answerArray || answerArray.length == 0) { this.props.showNotification('请先点击选择本选择题的正确选项'); return; } @@ -119,9 +119,9 @@ class SingleEditor extends Component{ "question_type":1, "question_score":5, "question_choices":["a答案","b答案","c答案","d答案"], - "standard_answers":[1] + "standard_answers":[1] }*/ - const Id = this.props.match.params.Id + const Id = this.props.match.params.Id if (question_id) { const editUrl = this.props.getEditQuestionUrl(question_id); axios.put(editUrl, { @@ -144,7 +144,7 @@ class SingleEditor extends Component{ }); } else { const url = this.props.getAddQuestionUrl(); - + axios.post(url, { exercise_bank_id: Id, question_title, @@ -162,16 +162,16 @@ class SingleEditor extends Component{ .catch(function (error) { console.log(error); }); - } + } } onCancel = () => { this.props.onEditorCancel() } - + componentDidMount = () => { - + } onOptionClick = (index) => { // if (this.props.exerciseIsPublish) { @@ -186,7 +186,7 @@ class SingleEditor extends Component{ // TODO 新建,然后删除CD选项,再输入题干,会调用到这里,且index是3 return; } - let question_choices = this.state.question_choices.slice(0); + let question_choices = this.state.question_choices.slice(0); question_choices[index] = value; this.setState({ question_choices }) } @@ -200,19 +200,19 @@ class SingleEditor extends Component{ mdReactObject.toShowMode() } this.mdReactObject = that; - + } toShowMode = () => { - + } render() { let { question_title, question_score, question_type, question_choices, standard_answers } = this.state; let { question_id, index, exerciseIsPublish, - // question_title, - // question_type, + // question_title, + // question_type, // question_score, isNew } = this.props; - + // const { getFieldDecorator } = this.props.form; const isAdmin = this.props.isAdmin() @@ -221,8 +221,8 @@ class SingleEditor extends Component{ const qNumber = `question_${index}`; // TODO show模式 isNew为false isEdit为false - // [true, false, true] -> [0, 2] - + // [true, false, true] -> [0, 2] + const answerTagArray = standard_answers.map((item, index) => { return item == true ? tagArray[index] : -1 }).filter(item => item != -1); return(
    @@ -253,8 +253,8 @@ class SingleEditor extends Component{ ref="titleEditor" > - - {question_choices.map( (item, index) => { + + {question_choices.map( (item, index) => { const bg = standard_answers[index] ? 'check-option-bg' : '' return
    {/* 点击设置答案 */} @@ -268,7 +268,7 @@ class SingleEditor extends Component{ {/* */}
    - {/* {!exerciseIsPublish && 新增选项} */} - - {!exerciseIsPublish ? '温馨提示:点击选项标题,可以直接设置答案;选择多个答案即为多选题' : ' '} + + {!exerciseIsPublish ? '温馨提示:点击选项输入框可设置答案;选中的选项即为正确答案,选择多个答案即为多选题' : ' '} { answerTagArray && !!answerTagArray.length ? {answerTagArray.join(' ')} 标准答案: - : - 请点击正确选项 + : + 温馨提示:点击选项输入框可设置答案;选中的选项即为正确答案,选择多个答案即为多选题 }
    @@ -310,18 +311,18 @@ class SingleEditor extends Component{  分 - + 取消 保存 - +
    - +
    ) } } // RouteHOC() -export default (SingleEditor); \ No newline at end of file +export default (SingleEditor); diff --git a/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js b/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js index 465f3d590..5253eb94f 100644 --- a/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js +++ b/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js @@ -458,6 +458,7 @@ class Listofworksstudentone extends Component { : this.Viewstudenttraininginformationtysl2(e, record)} onClick={() => this.Viewstudenttraininginformation(record)}>{record.operating} } @@ -810,6 +811,7 @@ class Listofworksstudentone extends Component { : this.Viewstudenttraininginformationtysl2(e, record)} onClick={() => this.Viewstudenttraininginformation(record)}>{record.operating} } @@ -1177,6 +1179,7 @@ class Listofworksstudentone extends Component { onClick={() => this.Adjustment(record)}>调分
    : this.Viewstudenttraininginformationtysl2(e, record)} onClick={() => this.Viewstudenttraininginformationt(record)}>查看 ) @@ -1509,6 +1512,7 @@ class Listofworksstudentone extends Component { onClick={() => this.Adjustment(record)}>调分 : this.Viewstudenttraininginformationtysl2(e, record)} onClick={() => this.Viewstudenttraininginformationt(record)}>{record.operating} ) @@ -2783,7 +2787,16 @@ class Listofworksstudentone extends Component { } // 调分 - + Viewstudenttraininginformationtysl2 = (e, data) => { + // console.log("Viewstudenttraininginformationtysl2"); + // console.log("shubiao zhongjian "); + // console.log(e); + this.setState({ + userids: data.myid, + }) + // this.viewtrainingt(e.myid); + window.open(`/courses/${this.state.props.match.params.coursesId}/shixun_homeworks/${data.myid}/shixun_work_report`, '_blank'); + } // 查看学员实训信息 Viewstudenttraininginformationt = (e) => { // console.log("Viewstudenttraininginformation"); diff --git a/public/react/src/modules/courses/shixunHomework/ShixunHomeworkPage.js b/public/react/src/modules/courses/shixunHomework/ShixunHomeworkPage.js index cd61d02d2..1df901d97 100644 --- a/public/react/src/modules/courses/shixunHomework/ShixunHomeworkPage.js +++ b/public/react/src/modules/courses/shixunHomework/ShixunHomeworkPage.js @@ -117,12 +117,12 @@ class ShixunHomeworkPage extends Component { /// 重做的确认 ModalSaves=()=>{ - this.setState({ - ModalsType:false, - Modalstopval:"" - }); + this.setState({ + ModalsType:false, + Modalstopval:"" + }); if(this.state.teacherdatapage){ - this.resetshixunCombat(this.state.teacherdatapage.myshixun_identifier); + this.resetshixunCombat(this.state.teacherdatapage.myshixun_identifier); } try { console.log("this.child"); @@ -149,29 +149,29 @@ class ShixunHomeworkPage extends Component { } //重置按钮 resetshixunCombat=(id)=>{ - this.setState({ - mylistisSpin:true, + this.setState({ + mylistisSpin:true, + }) + let zrl=`/myshixuns/${id}/reset_my_game.json`; + axios.get(zrl).then((response) => { + // window.location.href = "/shixuns/" + response.data.shixun_identifier + "/challenges"; + this.setState({ + mylistisSpin:false, + }) + this.child.Isupdatass(); + this.props.showNotification("已清空本实训的学习记录\n" + + "\n" + + "请点击“开启挑战”重做实训作业"); + }).catch((error) => { + this.setState({ + mylistisSpin:false, }) - let zrl=`/myshixuns/${id}/reset_my_game.json`; - axios.get(zrl).then((response) => { - // window.location.href = "/shixuns/" + response.data.shixun_identifier + "/challenges"; - this.setState({ - mylistisSpin:false, - }) - this.child.Isupdatass(); - this.props.showNotification("已清空本实训的学习记录\n" + - "\n" + - "请点击“开启挑战”重做实训作业"); - }).catch((error) => { - this.setState({ - mylistisSpin:false, - }) - console.log(error) - }); + console.log(error) + }); } bindRef = ref => { this.child = ref } ///////////////教师截止 - //编辑作业 + //编辑作业 Showupdateinstructionsboolfalse (bool) { this.setState({ Showupdateinstructions:bool @@ -183,7 +183,7 @@ class ShixunHomeworkPage extends Component { Showupdateinstructions:true }) } - gotohome=()=>{ + gotohome=()=>{ // console.log(this.props) let {jobsettingsdatapage}=this.state @@ -194,7 +194,7 @@ class ShixunHomeworkPage extends Component { const isAdmin = this.props.isAdmin(); // console.log(119) - // console.log(jobsettingsdatapage); + // console.log(jobsettingsdatapage); document.title=jobsettingsdatapage === undefined ? "" : jobsettingsdatapage.data.course_name; return (
    @@ -224,34 +224,34 @@ class ShixunHomeworkPage extends Component {
    } -
    -

    - {teacherdatapage === undefined ? "" : teacherdatapage.homework_name} -

    - - this.gotohome()}>返回 - 实训详情 +
    +

    + {teacherdatapage === undefined ? "" : teacherdatapage.homework_name} +

    + + this.gotohome()}>返回 + 实训详情 -
    -
    -
    -
    - this.ChangeTab(0)}>作品列表 - this.ChangeTab(1)}>作业描述 - {this.props.isAdmin() ? - this.state.code_review === true || jobsettingsdatapage === undefined ? [""] : jobsettingsdatapage.data.homework_status[0] === "未发布" ? "" : - this.ChangeTab(2)}> - 代码查重 : ""} - {parseInt(tab) === 3? - - :""} + } + :""} - this.ChangeTab(3)} - >{this.props.isAdmin()?"设置":"得分规则"} - {/*{this.props.isAdmin() ? 导出 : ""}*/} - - {this.props.isAdmin() ? -
  • - 导出 - +
  • : ""} + {this.props.isAdmin() ? + teacherdatapage && teacherdatapage.end_immediately === true ? + this.homeworkendss(this.child)}>立即截止 + : "" + : ""} + {this.props.isAdmin() ? + teacherdatapage && teacherdatapage.publish_immediately === true ? + this.homeworkstarts(this.child)}>立即发布 + : "" + : ""} + {this.props.isAdmin() ? + teacherdatapage && teacherdatapage.code_review === true ? + this.workshowmodels(this.child)}>代码查重 + : "" : ""} + { + parseInt(tab)===1? + this.props.isAdmin() ? + this.edenwork()}>编辑作业 + :"" :"" - :"" - } + } - {this.state.view_report === true ? - 查看实训报告 - : ""} - { - teacherdatapage === undefined ? "" - : teacherdatapage.commit_des === null || teacherdatapage.commit_des === undefined ? "" : - {teacherdatapage.commit_des} - } - {teacherdatapage === undefined ? "" : } - {this.props.isStudent() ? - ( - teacherdatapage&&teacherdatapage.redo_work===true? - this.Modalcancelss()}>重做 - :"" - ) - : "" } + {this.state.view_report === true ? + 查看实训报告 + : ""} + { + teacherdatapage === undefined ? "" + : teacherdatapage.commit_des === null || teacherdatapage.commit_des === undefined ? "" : + {teacherdatapage.commit_des} + } + {teacherdatapage === undefined ? "" : } + {this.props.isStudent() ? + ( + teacherdatapage&&teacherdatapage.redo_work===true? + this.Modalcancelss()}>重做 + :"" + ) + : "" } + - - {parseInt(tab) === 0 ? this.Getdataback(jobsettingsdata, teacherdata)}>:""} - {parseInt(tab) === 1 ? this.Getdataback(jobsettingsdata, teacherdata)} Showupdateinstructionsboolfalse={(i)=>this.Showupdateinstructionsboolfalse(i)}>:""} - {parseInt(tab) === 2 ? this.Getdataback(jobsettingsdata, teacherdata)}>:""} - {parseInt(tab) === 3 ? this.Getdataback(jobsettingsdata, teacherdata)}>:""} - + {parseInt(tab) === 0 ? this.Getdataback(jobsettingsdata, teacherdata)}>:""} + {parseInt(tab) === 1 ? this.Getdataback(jobsettingsdata, teacherdata)} Showupdateinstructionsboolfalse={(i)=>this.Showupdateinstructionsboolfalse(i)}>:""} + {parseInt(tab) === 2 ? this.Getdataback(jobsettingsdata, teacherdata)}>:""} + {parseInt(tab) === 3 ? this.Getdataback(jobsettingsdata, teacherdata)}>:""} + ) diff --git a/public/react/src/modules/courses/statistics/Statistics.js b/public/react/src/modules/courses/statistics/Statistics.js index 8b22f2c25..31f897c21 100644 --- a/public/react/src/modules/courses/statistics/Statistics.js +++ b/public/react/src/modules/courses/statistics/Statistics.js @@ -160,7 +160,18 @@ class Statistics extends Component{ derivefun=(url)=>{ let{group_ids}=this.state; - this.props.slowDownload(`${url}?group_id=${group_ids}`); + let list=group_ids; + let urllist=""; + if(list!=undefined&&list.length!=0) + list.map((item,key)=>{ + if(key===0){ + urllist=`group_id[]=${item}` + }else{ + urllist=urllist+`&group_id[]=${item}` + } + + }) + this.props.slowDownload(`${url}?${urllist}`); } diff --git a/public/react/src/modules/home/shixunsHome.js b/public/react/src/modules/home/shixunsHome.js index 4db39a310..217e1cc06 100644 --- a/public/react/src/modules/home/shixunsHome.js +++ b/public/react/src/modules/home/shixunsHome.js @@ -147,7 +147,9 @@ class ShixunsHome extends Component { nextArrow={} prevArrow={} autoplay + autoplaySpeed={4500} animation={false} + pauseOnHover={true} style={{width:"100%"}} arrowPos="outer"> {homedatalist.images_url.map((item, index) => ( diff --git a/public/react/src/modules/login/LoginDialog.css b/public/react/src/modules/login/LoginDialog.css index 9a9373770..37e2f48b6 100644 --- a/public/react/src/modules/login/LoginDialog.css +++ b/public/react/src/modules/login/LoginDialog.css @@ -136,12 +136,18 @@ .startlogin{ color:#888; } + .weixinheight390{ height: 390px; } + +.qqheight390{ + width: 450px; + height: 390px; +} #log_reg_content { padding: 38px 30px 20px !important; } .textcenter{ text-align: center; -} \ No newline at end of file +} diff --git a/public/react/src/modules/login/LoginDialog.js b/public/react/src/modules/login/LoginDialog.js index 6bd6ac41f..940e70c9a 100644 --- a/public/react/src/modules/login/LoginDialog.js +++ b/public/react/src/modules/login/LoginDialog.js @@ -7,7 +7,7 @@ import Dialog, { DialogContentText, DialogTitle, } from 'material-ui/Dialog'; -import {notification } from 'antd'; +import {notification,Modal } from 'antd'; import axios from 'axios'; @@ -104,8 +104,8 @@ class LoginDialog extends Component { MyEduCoderModals:false, Phonenumberisnotco:undefined, Phonenumberisnotcobool:false, - weixinlogin:false - + weixinlogin:false, + qqlogin:false }; } enter=(num) =>{ @@ -529,14 +529,30 @@ class LoginDialog extends Component { weixinlogin:true }) } + openqqlogin=()=>{ + this.setState({ + qqlogin:true + }) + //window.location.href=`https://graph.qq.com/oauth2.0/show?which=Login&display=pc&client_id=101508858&redirect_uri=https%3a%2f%2f${window.location.host}%2otherloginqq&response_type=code` + window.location.href=`https://graph.qq.com/oauth2.0/show?which=Login&display=pc&client_id=101508858&redirect_uri=https%3a%2f%2f${window.location.host}%2fotherloginqq&response_type=code` + // window.location.href=`https://graph.qq.com/oauth2.0/show?which=Login&display=pc&client_id=101508858&redirect_uri=https%3a%2f%2fwww.educoder.net%2fotherloginstart&tp=qq&response_type=code` + } + + openphoneqqlogin=()=>{ + window.open( + `https://xui.ptlogin2.qq.com/cgi-bin/xlogin?appid=716027609&pt_3rd_aid=101508858&daid=383&pt_skey_valid=0&style=35&s_url=http%3A%2F%2Fconnect.qq.com&refer_cgi=authorize&which=&client_id=101508858&response_type=code&scope=get_user_info&redirect_uri=https%3a%2f%2ftest-newweb.educoder.net%2fotherloginqq&response_type=code` + ) + } + hideweixinlogin=()=>{ this.setState({ - weixinlogin:false + weixinlogin:false, + qqlogin:false }) } render() { - let{open,login,speedy,loginValue,regular,isGoing,isGoingValue,disabled,bottonclass,Phonenumberisnotco, - dialogBox,shortcutnum,disabledType,gaincode,authCodeType,authCodeclass, isRender,weixinlogin}=this.state; + let{qqlogin,login,isGoing,isGoingValue,disabled,bottonclass,Phonenumberisnotco, + dialogBox, isRender,weixinlogin}=this.state; if (isRender === undefined) { isRender = false @@ -659,8 +675,22 @@ class LoginDialog extends Component { this.openweixinlogin()}> 微信登录 + this.openqqlogin()} className={"ml10"}> + qq登录 + -

    :""} +

    :

    + + ———————— 快速登录 ———————— +

    +

    } } {weixinlogin===true?:""} - {weixinlogin===true?

    + + + {weixinlogin===true?

    this.hideweixinlogin()}>返回账号登录

    :""} @@ -690,110 +722,3 @@ class LoginDialog extends Component { export default LoginDialog ; - -// onkeypress="user_login_keypress(event);" - -// onkeypress="user_login_keypress(event);" - - -{/*
    -
    -
    -

    -
    -
    } - - - -{/*第三方账号登录*/} - -{/*
    -

    第三方账号登录

    -
    - - - -
    -
    } - -// -// {/*
    */} -// {/*
    */} -// {/*
    */} -// {/**/} -// {/**/} -// {/*
    */} -// {/**/} -// {/**/} -// {/**/} -// {/*
    */} -// {/*

    请输入有效的手机号/邮箱号*/} -// {/*

    */} -// {/*
    */} -// -// {/*
    */} -// {/*/!*drag*/ }*/} -// {/*
    */} -// {/*
    */} -// {/*
    */} -// {/*请按住滑块,拖动到最右边*/} -// {/*
    */} -// {/*
    */} -// {/*
    */} -// {/*
    */} -// {/*

    请先拖动滑块完成验证

    */} -// {/*
    */} -// {/*
    */} -// -// {/*

    */} -// {/**/} -// {/**/} -// {/**/} -// {/*

    */} -// -// {/*
    */} -// {/*

    */} -// {/*请输入验证码*/} -// {/*

    */} -// {/*
    */} -// -// {/**/} -// -// {/*

    */} -// -// {/**/} -// {/**/} -// {/**/} -// {/**/} -// -// {/**/} -// {/*忘记密码*/} -// {/*注册*/} -// {/**/} -// -// {/*

    */} -// {/**/} -// {/*
    */} diff --git a/public/react/src/modules/login/Otherlogin.js b/public/react/src/modules/login/Otherlogin.js index 73f0c6dc6..59710ab2f 100644 --- a/public/react/src/modules/login/Otherlogin.js +++ b/public/react/src/modules/login/Otherlogin.js @@ -132,6 +132,8 @@ class Otherlogin extends Component { } postwechatlogin=(type,username,password)=>{ + let query=this.props.location.search; + const types = query.split('?type='); if(type===false){ if(username===undefined||username===""||username===null){ this.setState({ @@ -146,9 +148,11 @@ class Otherlogin extends Component { return } } + + let url = "/bind_user.json"; axios.post(url, { - type: 'wechat', + type: types[1]==="qq"?"qq":'wechat', not_bind:type, username:username, password:password diff --git a/public/react/src/modules/login/Otherloginqq.js b/public/react/src/modules/login/Otherloginqq.js new file mode 100644 index 000000000..30407bf3c --- /dev/null +++ b/public/react/src/modules/login/Otherloginqq.js @@ -0,0 +1,58 @@ +import React, { Component } from 'react'; + +import { BrowserRouter as Router, Route, Link } from "react-router-dom"; + +import { Spin } from 'antd'; +import axios from 'axios'; +class Otherloginqq extends Component { + + componentDidMount() { + let query=this.props.location.search; + + const type = query.split('?code='); + const types = type[1].split('&state='); + let codeurl = `/auth/qq/callback`; + axios.get(codeurl,{params:{ + code:type[1], + redirect_uri:`https://${window.location.host}/otherloginqq` + }}).then((result)=> { + if(result){ + if(result.data.status===0){ + if(result.data.new_user===true){ + window.location.href="/otherlogin?type=qq" + }else{ + // this.getinfo() + if(types[1]==="account"){ + window.location.href="/account/binding" + }else{ + window.location.href="/" + } + + } + } + } + }).catch((error)=>{ + + }) + } + + render() { + // Loading + return ( +
    + + +
    + ); + } +} + +export default Otherloginqq; \ No newline at end of file diff --git a/public/react/src/modules/login/Otherloginstart.js b/public/react/src/modules/login/Otherloginstart.js index fc5d46bbc..9901fc8ad 100644 --- a/public/react/src/modules/login/Otherloginstart.js +++ b/public/react/src/modules/login/Otherloginstart.js @@ -8,31 +8,34 @@ class Otherloginstart extends Component { componentDidMount() { let query=this.props.location.search; - const type = query.split('?code='); - const types = type[1].split('&state='); - console.log(types) - let codeurl = `/auth/wechat/callback.json` - axios.get(codeurl,{params:{ - code:types[0] - }}).then((result)=> { - if(result){ - if(result.data.status===0){ - if(result.data.new_user===true){ - window.location.href="/otherlogin" - }else{ - // this.getinfo() - if(types[1]==="account"){ - window.location.href="/account/binding" + debugger + if(query!= ""){ + const type = query.split('?code='); + const types = type[1].split('&state='); + let codeurl = `/auth/wechat/callback.json` + axios.get(codeurl,{params:{ + code:types[0] + }}).then((result)=> { + if(result){ + if(result.data.status===0){ + if(result.data.new_user===true){ + window.location.href="/otherlogin?type=wechat" }else{ - window.location.href="/" - } + // this.getinfo() + if(types[1]==="account"){ + window.location.href="/account/binding" + }else{ + window.location.href="/" + } + } } } - } - }).catch((error)=>{ + }).catch((error)=>{ + + }) + } - }) } diff --git a/public/react/src/modules/page/component/monaco/TPIMonaco.js b/public/react/src/modules/page/component/monaco/TPIMonaco.js index b814ecb44..59cb5ce35 100644 --- a/public/react/src/modules/page/component/monaco/TPIMonaco.js +++ b/public/react/src/modules/page/component/monaco/TPIMonaco.js @@ -226,6 +226,7 @@ class TPIMonaco extends Component { // https://github.com/Microsoft/monaco-editor/issues/539 window.monaco.editor.setModelLanguage(editor_monaco.getModel(), lang) } else if (prevProps.isEditablePath != this.props.isEditablePath) { + // 当前文件是否可编辑 if (this.props.isEditablePath || this.props.shixun && this.props.shixun.code_edit_permission == true) { editor_monaco.updateOptions({readOnly: false}) } else { @@ -250,6 +251,7 @@ class TPIMonaco extends Component { } } componentWillUnmount() { + // 注意销毁,不然会出现不能编辑的bug this.editor_monaco && this.editor_monaco.dispose() } diff --git a/public/react/src/modules/page/readme.txt b/public/react/src/modules/page/readme.txt index f744848fc..882c48ee5 100644 --- a/public/react/src/modules/page/readme.txt +++ b/public/react/src/modules/page/readme.txt @@ -1,3 +1,131 @@ +state说明 + tasks详情接口 + allowed_unlock 为true时,才允许非管理员用户解锁隐藏测试集 + discusses_count 总评论数 + + challenge 实训关卡信息 + exec_time -- + modify_time -- + path 关卡文件路径 + position 第几关 + praises_count 点赞数 + score 分数 + shixun_id + st 0-编程题 1-选择题 + subject 关卡名称 + task_pass 过关任务 + web_route -- + + game 为每一个用户独立创建的实训关卡对应的信息 + accuracy -- + answer_deduction-- + answer_open -- + challenge_id + cost_time 通关耗时 + created_at + end_time + evaluate_count + final_score + id + identifier + modify_time + myshixun_id + open_time + picture_path + resubmit_identifier + retry_status + star + status 2-已通关 + test_sets_view true-测试集已解锁 + updated_at + user_id + game_count 关卡数 + git_url 仓库地址,vnc会用到 + has_answer + is_teacher 是否是老师 初始化被赋值到 user.is_teacher + last_compile_output + mirror_name 镜像名称 TPIMonaco会用到这个属性来判断当前关卡使用的什么语言 见 mirror2LanguageMap + myshixun + commit_id: "80cb6fc55a14bdd64a9c99913f416966238ed3de" + created_at: "2019-07-26T09:00:31.000+08:00" + git_url: null + gpid: null + id: 542543 + identifier: "ns53g8vfeo" 有些接口会用到 + is_public: true + modify_time: "2017-11-02T18:12:23.000+08:00" + onclick_time: "2019-07-26T09:00:31.000+08:00" + repo_name: "p15478209/ns53g8vfeo20190726090031" + reset_time: "2017-10-25T09:33:03.000+08:00" + shixun_id: 61 + status: 0 + system_tip: true (如果修改了测试集 || 修改了代码) && system_tip为true 也就是下面代码为true时,才显示更新通知弹框 + const showUpdateButton = (tpm_cases_modified || needUpdateScript) && myshixun.system_tip === true; + updated_at: "2019-11-05T10:58:35.000+08:00" + user_id: 24731 + myshixun_manager: true + next_game: "so7ijzqe63a9" 下一关identifier + praise_count: 120 点赞数 + prev_game: "bxg5w9uonhts" 上一关identifier + record_onsume_time: 0.296 上一次评测耗时 初始化被赋值到newResData.record = newResData.record_onsume_time + sets_error_count: 0 失败测试集数量 + shixun + authentication: false + averge_star: 4.9 + can_copy: false + challenges_count: 4 关卡数 + closer_id: null + code_edit_permission: false 是否允许修改代码 + code_hidden: false 是否隐藏文件目录按钮 + created_at: "2017-06-09T11:32:16.000+08:00" + end_time: null + excute_time: null + exec_time: 25 + forbid_copy: false forbid_copy ? "不允许学员复制和粘贴代码" : "允许学员复制和粘贴代码" + fork_from: null + git_url: "educoder/uznmbg54" + gpid: 2448 + hidden: false + hide_code: false 是否隐藏代码tab + homepage_show: true + id: 61 + identifier: "uznmbg54" + image_text: null + language: "Python3.6" !! + major_id: 635 + mirror_script_id: null + modify_time: "2017-11-02T18:12:23.000+08:00" + multi_webssh: false 多命令行tab + myshixuns_count: 9655 学员数 + name: "Python表达式问题求解(一)※" + opening_time: null + pod_life: 0 + publish_time: "2017-09-01T10:37:49.000+08:00" + repo_name: "educoder/uznmbg54" + reset_time: "2017-10-25T09:33:03.000+08:00" + sigle_training: false + status: 2 shixun.status >= 2 实训已发布 shixun.status <= 1 模拟实战 + task_pass: task_pass ? "允许学员跳关挑战" : "不允许学员跳关挑战" + test_set_permission: true test_set_permission ? "允许学员通过金币解锁查看测试集内容" : "不允许学员通过金币解锁查看测试集内容" + trainee: 1 + updated_at: "2019-10-11T08:50:59.000+08:00" + use_scope: 0 + user_id: 3039 + users_count: 4 + visits: 69699 + webssh: 1 是否显示命令行tab + st 0-编程题 1-选择题 + test_sets 测试集 + test_sets_count: 1 + time_limit: 25 game_status.json轮训次数 + tomcat_url: "http://47.96.157.89" web类型实训,可以打开展现一个测试服务,用来查看评测结果 const webDisplayUrl = `${tomcat_url}:${data.port}/${path}` + tpm_cases_modified: false 参考system_tip属性 + tpm_modified: true 参考system_tip属性 + user 当前关卡所属用户的信息 + user_praise 当前用户是否点赞 + +-------------- -------------- -------------- -------------- -------------- -------------- -------------- -------------- -------------- + TPIContextProvider tpi主要的state容器,主要接口:`/tasks/${stageId}.json`,一次性获取所有tpi首屏展示所需要的信息,除了代码内容。 接口返回的内容包括 @@ -20,3 +148,55 @@ TPIContextProvider 代码内容通过以下接口获取: `/tasks/${game.identifier}/rep_content.json?path=${path}&status=${status}&retry=${isRetry ? 1 : 0}` +层次结构 +TPIContextProvider + page/Index + Header + TaskListContainer + TaskList 左侧划出的任务列表 + MainContentContainer + MainContent + LeftViewContainer 左侧区域 + LeftView + ChooseAnswerView 选择题答案 + CommentContainer + Comments 评论列表 + CodeEvaluateMultiLevelAnswerUnlock 多级别解锁 + + // 看设置,是vnc or 代码 or 选择题 + CodeRepositoryViewContainer for VNC + VNCContainer + CodeEvaluateView 代码评测结果 + VNCDisplay vnc显示 + ActionView 评测按钮区 + || CodeRepositoryViewContainer 代码显示区 + WebSSHTimer ssh倒计时 + TPIMonaco monaco编辑器 + || ChooseRepositoryView 选择题显示区 + + // 看设置,是代码 or 选择题 + CodeEvaluateView + || ChooseEvaluateView + + ActionView 评测按钮区 + +没用的文件 + LeftNav.js + AnswerListContainer.js left 他人解答 + + + + + +TPI SSH + 命令行的js资源都位于这个目录:/react/public/js/jsFromMiddleLayer/base64.js + + /page/main/CodeRepositoryView.js文件中,open_webssh.json接口返回后,会根据代码区试图大小计算ssh视图的大小(同样的逻辑在js_min_all中也有: + var h = $("#games_repository_contents").height() - $("#top_repository").height() - repositoryTabHeight; ) + 这里有个对应的issue https://www.trustie.net/issues/25279 + 这里是要判断特殊的屏幕(公司dell笔记本可重现),针对这些情况处理,加高命令行的高度 + ps js_min_all中搜`$("#games_repository_contents").height()`可以找到相关代码 + + +VNCDisplay + 使用的github上的代码 https://github.com/novnc/noVNC/ \ No newline at end of file diff --git a/public/react/src/modules/paths/PathDetail/Modifytext.js b/public/react/src/modules/paths/PathDetail/Modifytext.js new file mode 100644 index 000000000..ca12659a9 --- /dev/null +++ b/public/react/src/modules/paths/PathDetail/Modifytext.js @@ -0,0 +1,169 @@ +import React, {Component} from 'react'; +import {Button, Layout, Input, Form} from 'antd'; +import axios from 'axios'; +import {getImageUrl} from 'educoder'; + + +class Modifytext extends Component { + constructor(props) { + super(props) + this.state = {} + } + + componentDidMount() { + + } + + //重新输入教学模式 + Modifytext = () => { + this.props.form.validateFieldsAndScroll((err, values) => { + if (!err) { + const url = `/paths/${this.props.pathid}/update_team_title.json`; + axios.post(url, { + team_title: values.teachingteam + }).then((response) => { + console.log(response); + if (response) { + if (response.data) { + if (response.data.status === 0) { + try { + this.props.showNotification("修改成功!"); + } catch (e) { + + } + try { + this.props.modifysy(2); + } catch (e) { + + } + + + } + } + } + + }).catch((error) => { + console.log(error) + + }) + + + } + }) + + + } + + + render() { + const {getFieldDecorator} = this.props.form; + return ( +
    +
    + +
    + +
    +
    + + {getFieldDecorator('teachingteam', { + rules: [{ + // initialValue: this.state.cityDefaultValue, + required: true, + message: '请输入模式', + }], + })( + + )} + +
    +

    +
    + {/*
    this.yhBanksfalse()}>

    取消

    */} + +
    +
    +
    +
    +
    +
    + +
    +
    + ) + } +} + +const Modifytexts = Form.create({name: 'Modifytext'})(Modifytext); + +export default Modifytexts; + diff --git a/public/react/src/modules/paths/PathDetail/PathDetailIndex.js b/public/react/src/modules/paths/PathDetail/PathDetailIndex.js index ca52cd9d1..b393d1bb6 100644 --- a/public/react/src/modules/paths/PathDetail/PathDetailIndex.js +++ b/public/react/src/modules/paths/PathDetail/PathDetailIndex.js @@ -12,7 +12,7 @@ import Modals from '../../modals/Modals'; import axios from 'axios'; import TPMRightSection from "../../tpm/component/TPMRightSection"; import styled from "styled-components"; - +import Modifytext from './Modifytext'; const getItemStyle = (isDragging, draggableStyle) => ({ // change background colour if dragging background: isDragging ? '#dceeff' : '', @@ -87,7 +87,9 @@ class PathDetailIndex extends Component{ dataquerys:{}, MenuItemsindex:1, MenuItemsindextype:0, - qrcode_img:null + qrcode_img: null, + team_title: "教学团队", + modify: false, } this.onDragEnd = this.onDragEnd.bind(this); @@ -256,6 +258,7 @@ class PathDetailIndex extends Component{ progress:result.data.progress, members:result.data.members, items: getItems(result.data.members.length), + team_title: result.data.team_title }) }).catch((error)=>{ @@ -321,6 +324,7 @@ class PathDetailIndex extends Component{ progress:result.data.progress, members:result.data.members, items: getItems(result.data.members.length), + team_title: result.data.team_title }) }).catch((error)=>{ @@ -458,6 +462,50 @@ class PathDetailIndex extends Component{ console.log(error) }) } + + + modifysy = (i) => { + if (i === 1) { + this.setState({ + modify: true + }) + } else if (i === 2) { + this.setState({ + modify: false + }) + let righturl = "/paths/" + this.props.match.params.pathId + "/right_banner.json"; + axios.get(righturl).then((result) => { + if (result.data.status === 407 || result.data.status === 401) { + debugger + return; + } + + if (result.data.status === 403) { + debugger + // window.location.href = "/403"; + return; + } + + this.setState({ + // detailInfoList:result.data, + tags: result.data.tags, + progress: result.data.progress, + members: result.data.members, + items: getItems(result.data.members.length), + team_title: result.data.team_title + }) + + }).catch((error) => { + console.log(error); + }) + } + } + + setteam_title(name) { + this.setState({ + team_title: name + }) + } render(){ this.updatamakedown("shixuns_propaedeutics"); @@ -475,7 +523,9 @@ class PathDetailIndex extends Component{ tags, qrcode_img, MenuItemsindex, - MenuItemsindextype + MenuItemsindextype, + team_title, + modify } = this.state @@ -613,7 +663,19 @@ class PathDetailIndex extends Component{ { members ===undefined ?"":members === null ?"":
    -

    教学团队

    + { + detailInfoList === undefined ? "" : detailInfoList.allow_add_member === true ? + ( + modify === false ? +

    this.modifysy(1)}>{team_title}

    + : + this.modifysy(i)} + setteam_title={(name) => this.setteam_title(name)}> + ) + + : "" + } { members===undefined? members && members.map((item,key)=>{ @@ -712,4 +774,4 @@ class PathDetailIndex extends Component{ ) } } -export default PathDetailIndex; \ No newline at end of file +export default PathDetailIndex; diff --git a/public/react/src/modules/tpm/challengesnew/TPMMDEditor.js b/public/react/src/modules/tpm/challengesnew/TPMMDEditor.js index 2e6184428..11b88a037 100644 --- a/public/react/src/modules/tpm/challengesnew/TPMMDEditor.js +++ b/public/react/src/modules/tpm/challengesnew/TPMMDEditor.js @@ -132,6 +132,7 @@ function create_editorMD(id, width, high, placeholder, imageUrl, callback, initV // Or return editormd.toolbarModes[name]; // full, simple, mini // Using "||" set icons align right. const icons = ["bold", "italic", "|", "list-ul", "list-ol", "|", "code", "code-block", "link", "|", "testIcon", "testIcon1", '|', "image", "table", '|', "watch", "clear"]; + // 试卷处用到的填空题新增按钮 if (__that.props.showNullButton) { icons.push('nullBtton') } @@ -228,12 +229,14 @@ export default class TPMMDEditor extends Component { const imageUrl = `/api/attachments.json`; // 创建editorMd let react_id = `react_${_id}`; + // 将实例存到了window window[react_id] = this const answers_editormd = create_editorMD(_id, '100%', this.props.height, _placeholder, imageUrl, (_editorName) => { const __editorName = _editorName; react_id = `react_${__editorName.id}`; const that = window[react_id] - + + // 一个延迟的recreate或resize,不加这段代码,md初始化可能会出现样式问题 setTimeout(() => { if (that.props.needRecreate == true) { __editorName.recreate() // 注意 必须在setValue之前触发,不然会清空 @@ -268,6 +271,7 @@ export default class TPMMDEditor extends Component { that.props.onCMBeforeChange(cm,change) }) that.answers_editormd = __editorName; + // 这里应该可以去掉了,方便调试加的 window[__editorName.id+'_'] = __editorName; }, initValue, this.onEditorChange,this.props.watch, { noStorage: this.props.noStorage, @@ -276,6 +280,7 @@ export default class TPMMDEditor extends Component { }, this); } + // 用在form里时,validate失败时出现一个红色边框 showError = () => { this.setState({showError: true}) } diff --git a/public/react/src/modules/tpm/challengesnew/TPMevaluation.js b/public/react/src/modules/tpm/challengesnew/TPMevaluation.js index a8e70cb44..2b140d93f 100644 --- a/public/react/src/modules/tpm/challengesnew/TPMevaluation.js +++ b/public/react/src/modules/tpm/challengesnew/TPMevaluation.js @@ -28,6 +28,8 @@ const Option = Select.Option; const RadioGroup = Radio.Group; +const { TextArea } = Input; + function create_editorMD(id, width, high, placeholder, imageUrl, callback) { var editorName = window.editormd(id, { width: width, @@ -1155,19 +1157,22 @@ export default class TPMevaluation extends Component {

    - - + + >
    匹配规则: this.changeEvaluationRule(e,key)}> diff --git a/public/react/src/modules/user/LoginRegisterComponent.js b/public/react/src/modules/user/LoginRegisterComponent.js index 52e0d6869..55a42b62d 100644 --- a/public/react/src/modules/user/LoginRegisterComponent.js +++ b/public/react/src/modules/user/LoginRegisterComponent.js @@ -68,6 +68,7 @@ class LoginRegisterComponent extends Component { registered:undefined, Phonenumberisnotcodmms:undefined, weixinlogin:false, + qqlogin:false } } if(props.loginstatus === false){ @@ -106,7 +107,7 @@ class LoginRegisterComponent extends Component { registered:undefined, Phonenumberisnotcodmms:undefined, weixinlogin:false, - + qqlogin:false } } } @@ -892,9 +893,25 @@ class LoginRegisterComponent extends Component { hideweixinlogin=()=>{ this.setState({ weixinlogin:false, + qqlogin:false, tab:["0"] }) } + + openqqlogin=()=>{ + this.setState({ + qqlogin:true + }) + //window.location.href=`https://graph.qq.com/oauth2.0/show?which=Login&display=pc&client_id=101508858&redirect_uri=https%3a%2f%2f${window.location.host}%2otherloginqq&response_type=code` + window.location.href=`https://graph.qq.com/oauth2.0/show?which=Login&display=pc&client_id=101508858&redirect_uri=https%3a%2f%2f${window.location.host}%2fotherloginqq&response_type=code` + // window.location.href=`https://graph.qq.com/oauth2.0/show?which=Login&display=pc&client_id=101508858&redirect_uri=https%3a%2f%2fwww.educoder.net%2fotherloginstart&tp=qq&response_type=code` + } + + openphoneqqlogin=()=>{ + window.open( + `https://xui.ptlogin2.qq.com/cgi-bin/xlogin?appid=716027609&pt_3rd_aid=101508858&daid=383&pt_skey_valid=0&style=35&s_url=http%3A%2F%2Fconnect.qq.com&refer_cgi=authorize&which=&client_id=101508858&response_type=code&scope=get_user_info&redirect_uri=https%3a%2f%2ftest-newweb.educoder.net%2fotherloginqq&response_type=code` + ) + } render() { const { // 登录 @@ -1040,12 +1057,31 @@ class LoginRegisterComponent extends Component { this.openweixinlogin()}> 微信登录 + this.openqqlogin()} className={"ml10"}> + qq登录 + +
    +

    :

    + + ———————— 快速登录 ———————— +

    -

    :""} +

    }
    } + + + + + { weixinlogin===false&&parseInt(tab[0])==1 &&
    @@ -1201,8 +1237,22 @@ class LoginRegisterComponent extends Component { this.openweixinlogin()}> 微信登录 + this.openqqlogin()} className={"ml10"}> + qq登录 + +
    +

    :

    + + ———————— 快速登录 ———————— +

    -

    :""} +

    } } {weixinlogin===true? -

    - this.handleCancel()}>取消 -

    - - - - + } + + + - +
    * 我们确保你所提供的信息均处于严格保密状态,不会泄露
    diff --git a/public/react/src/modules/user/usersInfo/Infos.js b/public/react/src/modules/user/usersInfo/Infos.js index a55cbb74c..488668421 100644 --- a/public/react/src/modules/user/usersInfo/Infos.js +++ b/public/react/src/modules/user/usersInfo/Infos.js @@ -280,7 +280,7 @@ class Infos extends Component{ } > - {/* 实训 */} + {/* 实训项目 */} () @@ -294,7 +294,7 @@ class Infos extends Component{ } > - {/* 项目 */} + {/* 开发项目 */} () diff --git a/public/react/src/modules/user/usersInfo/InfosCourse.js b/public/react/src/modules/user/usersInfo/InfosCourse.js index 14046d495..ec68261a3 100644 --- a/public/react/src/modules/user/usersInfo/InfosCourse.js +++ b/public/react/src/modules/user/usersInfo/InfosCourse.js @@ -71,8 +71,8 @@ class InfosCourse extends Component{ page:1, isSpin:true }) - let{status}=this.state; - this.getCourses(cate,status,1); + let {status, sort_by, sort_direction} = this.state; + this.getCourses(cate, status, 1, sort_by, sort_direction); } //切换状态 changeStatus=(status)=>{ @@ -81,8 +81,8 @@ class InfosCourse extends Component{ page:1, isSpin:true }) - let{category}=this.state; - this.getCourses(category,status,1); + let {category, sort_by, sort_direction} = this.state; + this.getCourses(category, status, 1, sort_by, sort_direction); } //切换页数 changePage=(page)=>{ @@ -90,8 +90,8 @@ class InfosCourse extends Component{ page, isSpin:true }) - let{category,status}=this.state; - this.getCourses(category,status,page); + let {category, status, sort_by, sort_direction} = this.state; + this.getCourses(category, status, page, sort_by, sort_direction); } // 进入课堂 @@ -110,7 +110,7 @@ class InfosCourse extends Component{ this.getCourses(category, status, 1, sort_by, "desc"); } - updatedlists(sort_direction, i) { + updatedlists(sort_directions, i) { // console.log("updatedlistssort_direction"); // console.log(sort_direction); // console.log(i); @@ -118,8 +118,20 @@ class InfosCourse extends Component{ this.setState({ isSpin: true }); - let {category, status, page, sort_by} = this.state; - this.getCourses(category, status, page, sort_by, sort_direction); + + let {category, status, page, sort_by, sort_direction} = this.state; + let sort_directiony = sort_directions; + if (sort_directions === "asc") { + if (sort_directions === sort_direction) { + sort_directiony = "desc" + } + } else if (sort_directions === "desc") { + if (sort_directions === sort_direction) { + sort_directiony = "asc" + } + } + + this.getCourses(category, status, page, sort_by, sort_directiony); } render(){ @@ -147,21 +159,87 @@ class InfosCourse extends Component{ ); - + console.log("InfosCourse"); + console.log(status); return(
    + + + { is_current && -
    -
  • this.changeStatus()}>全部
  • -
  • this.changeStatus("processing")}>正在进行
  • -
  • this.changeStatus("end")}>已结束
  • + }

    +

    + { category=="manage"? -
    -
  • this.changeStatus()}>全部
  • -
  • this.changeStatus("unpublished")}>未发布
  • -
  • this.changeStatus("bidding")}>竞标中
  • -
  • this.changeStatus("finished")}>已完成
  • + : category=="bidden"? -
    -
  • this.changeStatus()}>全部
  • -
  • this.changeStatus("bidding_lost")}>未中标
  • -
  • this.changeStatus("bidding_won")}>已中标
  • + :"" }

    @@ -289,4 +348,4 @@ class InfosPackage extends Component{ ) } } -export default InfosPackage; \ No newline at end of file +export default InfosPackage; diff --git a/public/react/src/modules/user/usersInfo/InfosPath.js b/public/react/src/modules/user/usersInfo/InfosPath.js index 0b1437f40..b91b29be5 100644 --- a/public/react/src/modules/user/usersInfo/InfosPath.js +++ b/public/react/src/modules/user/usersInfo/InfosPath.js @@ -123,13 +123,24 @@ class InfosPath extends Component{ } //排序 - updatedlists(sort_direction) { + updatedlists(sort_directions) { //是否是倒序 this.setState({ isSpin: true }); - let {category, status, page, sort_by} = this.state; - this.getCourses(category, status, sort_by, page, sort_direction); + let {category, status, page, sort_by, sort_direction} = this.state; + let sort_directiony = sort_directions; + if (sort_directions === "asc") { + if (sort_directions === sort_direction) { + sort_directiony = "desc" + } + } else if (sort_directions === "desc") { + if (sort_directions === sort_direction) { + sort_directiony = "asc" + } + } + + this.getCourses(category, status, sort_by, page, sort_directiony); } @@ -160,26 +171,97 @@ class InfosPath extends Component{ return(

    - + + + + { category && category == "manage" && is_current && -
    -
  • this.changeStatus()}>全部
  • -
  • this.changeStatus("editing")}>编辑中
  • -
  • this.changeStatus("applying")}>待审核
  • -
  • this.changeStatus("published")}>已发布
  • + } { category && category == "study" && is_current && -
    -
  • this.changeStatus()}>全部
  • -
  • this.changeStatus("unfinished")}>未完成
  • -
  • this.changeStatus("finished")}>已完成
  • + }
    - + + + { is_current && -
    -
  • this.changeStatus()}>全部
  • -
  • this.changeStatus("publicly")}>公开
  • -
  • this.changeStatus("personal")}>私有
  • + }

    { if(result){ @@ -124,13 +125,24 @@ class InfosShixun extends Component{ } //排序 - updatedlists(sort_direction) { + updatedlists(sort_directions) { //是否是倒序 this.setState({ isSpin: true }); - let {category, status, page, sort_by} = this.state; - this.getCourses(category, status, sort_by, page, sort_direction); + let {category, status, page, sort_by, sort_direction} = this.state; + let sort_directiony = sort_directions; + if (sort_directions === "asc") { + if (sort_directions === sort_direction) { + sort_directiony = "desc" + } + } else if (sort_directions === "desc") { + if (sort_directions === sort_direction) { + sort_directiony = "asc" + } + } + + this.getCourses(category, status, sort_by, page, sort_directiony); } render(){ @@ -160,27 +172,99 @@ class InfosShixun extends Component{ return(

    - + + + + { category && category == "manage" && is_current && -
    -
  • this.changeStatus()}>全部
  • -
  • this.changeStatus("editing")}>编辑中
  • -
  • this.changeStatus("applying")}>待审核
  • -
  • this.changeStatus("published")}>已发布
  • -
  • this.changeStatus("closed")}>已关闭
  • + } { category && category == "study" && is_current && -
    -
  • this.changeStatus()}>全部
  • -
  • this.changeStatus("processing")}>未通关
  • -
  • this.changeStatus("passed")}>已通关
  • + }
    { }, []) @@ -19,7 +19,16 @@ function InfoTab (props) {
    {categories && categories.map(item => { return ( -
  • changeCategory(item.key)}>{item.name}
  • + item.id === 1 ? +
  • changeCategory(item.key)} + style={{width: "70px"}}>{item.name}
  • + : +
  • changeCategory(item.key)} + style={{width: "80px"}}>{item.name}
  • ) })} {/*
  • this.changeCategory()}>全部
  • diff --git a/public/react/src/modules/user/usersInfo/usersInfo.css b/public/react/src/modules/user/usersInfo/usersInfo.css index 1cf335213..9bfabab9b 100644 --- a/public/react/src/modules/user/usersInfo/usersInfo.css +++ b/public/react/src/modules/user/usersInfo/usersInfo.css @@ -439,3 +439,15 @@ .h10 { height: 10px; } + +.w32 { + width: 32px !important; +} + +.w66 { + width: 66px !important; +} + +.w60 { + width: 60px !important; +} diff --git a/public/react/src/modules/user/usersInfo/video/InfosVideo.js b/public/react/src/modules/user/usersInfo/video/InfosVideo.js index 2cbea920b..bcc5acd2e 100644 --- a/public/react/src/modules/user/usersInfo/video/InfosVideo.js +++ b/public/react/src/modules/user/usersInfo/video/InfosVideo.js @@ -193,10 +193,31 @@ function InfoVideo (props) { } // TODO use封装 function onSortChange(key, index) { - const _item = _items[index] - _items.splice(index, 1) - _items.unshift(_item) - setSortKey(key) + + try { + const _item = _items[index]; + _items.splice(index, 1); + _items.unshift(_item); + const keys = key.split('-'); + const sorts = sortKey.split('-'); + if (key === "published_at-desc") { + if (keys[1] === sorts[1]) { + setSortKey("published_at-asc") + } else { + setSortKey(key) + } + } else if (key === "published_at-asc") { + if (keys[1] === sorts[1]) { + setSortKey("published_at-desc") + } else { + setSortKey(key) + } + } + } catch (e) { + + } + + } function getCopyText (file_url, cover_url) { return `` @@ -259,6 +280,23 @@ function InfoVideo (props) { .videoItem { margin-right: 24px; } + .white-panel li.active { + border-radius: 24px; + border: 0px solid #4CACFF; + color: #4CACFF; + } + .whitepanelysllisyt { + width: 70px !important; + height: 48px !important; + line-height: 46px !important; + + } + .whitepanelysllisyts { + width: 80px !important; + height: 48px !important; + line-height: 46px !important; + margin-left: 30px; + } `} @@ -266,10 +304,12 @@ function InfoVideo (props) { {...props} categories={[{ key: 'all', - name: '全部视频' + name: '全部视频', + id: 1, }, { key: 'review', - name: '待审核视频' + name: '待审核视频', + id: 2 }]} {...categoryObj} diff --git a/public/stylesheets/educoder/iconfont/demo_index.html b/public/stylesheets/educoder/iconfont/demo_index.html index 8a75ddb27..c88449b3f 100644 --- a/public/stylesheets/educoder/iconfont/demo_index.html +++ b/public/stylesheets/educoder/iconfont/demo_index.html @@ -222,6 +222,12 @@
    &#xe693;
    +
  • + +
    关注
    +
    &#xe6c0;
    +
  • +
  • 礼物
    @@ -324,6 +330,12 @@
    &#xe678;
  • +
  • + +
    关注
    +
    &#xe6c5;
    +
  • +
  • 喇叭
    @@ -1718,6 +1730,15 @@
  • +
  • + +
    + 关注 +
    +
    .icon-weibiaoti105 +
    +
  • +
  • @@ -1871,6 +1892,15 @@
  • +
  • + +
    + 关注 +
    +
    .icon-guanzhu +
    +
  • +
  • @@ -3740,6 +3770,14 @@
    #icon-renzhengxinxi
  • +
  • + +
    关注
    +
    #icon-weibiaoti105
    +
  • +
  • #icon-dashujucunchu
  • +
  • + +
    关注
    +
    #icon-guanzhu
    +
  • +