From cd717f1e1a3d191a9419ba595c84f6bfd8ae78fc Mon Sep 17 00:00:00 2001 From: p31729568 Date: Wed, 21 Aug 2019 15:07:14 +0800 Subject: [PATCH 001/252] oauth qq and wechat --- Gemfile | 4 ++ Gemfile.lock | 10 ++- app/controllers/accounts_controller.rb | 43 ------------ app/controllers/application_controller.rb | 18 +---- app/controllers/concerns/login_helper.rb | 69 +++++++++++++++++++ app/controllers/oauth/base_controller.rb | 20 ++++++ app/controllers/oauth/qq_controller.rb | 9 +++ app/controllers/oauth/wechat_controller.rb | 11 +++ app/libs/omniauth/strategies/qq.rb | 50 ++++++++++++++ app/libs/wechat_oauth.rb | 13 ++++ app/libs/wechat_oauth/error.rb | 14 ++++ app/libs/wechat_oauth/service.rb | 61 ++++++++++++++++ app/models/open_user.rb | 5 ++ app/models/open_users/qq.rb | 3 + app/models/open_users/wechat.rb | 3 + app/models/user.rb | 11 +++ .../create_or_find_qq_account_service.rb | 34 +++++++++ .../create_or_find_wechat_account_service.rb | 48 +++++++++++++ config/configuration.yml.example | 19 +++++ config/initializers/inflections.rb | 5 ++ config/initializers/omniauth.rb | 17 +++++ config/initializers/wechat_oauth_init.rb | 17 +++++ config/locales/oauth/wechat.zh-CN.yml | 4 ++ config/routes.rb | 2 + .../20190821054352_create_open_users.rb | 14 ++++ 25 files changed, 443 insertions(+), 61 deletions(-) create mode 100644 app/controllers/concerns/login_helper.rb create mode 100644 app/controllers/oauth/base_controller.rb create mode 100644 app/controllers/oauth/qq_controller.rb create mode 100644 app/controllers/oauth/wechat_controller.rb create mode 100644 app/libs/omniauth/strategies/qq.rb create mode 100644 app/libs/wechat_oauth.rb create mode 100644 app/libs/wechat_oauth/error.rb create mode 100644 app/libs/wechat_oauth/service.rb create mode 100644 app/models/open_user.rb create mode 100644 app/models/open_users/qq.rb create mode 100644 app/models/open_users/wechat.rb create mode 100644 app/services/oauth/create_or_find_qq_account_service.rb create mode 100644 app/services/oauth/create_or_find_wechat_account_service.rb create mode 100644 config/configuration.yml.example create mode 100644 config/initializers/omniauth.rb create mode 100644 config/initializers/wechat_oauth_init.rb create mode 100644 config/locales/oauth/wechat.zh-CN.yml create mode 100644 db/migrate/20190821054352_create_open_users.rb diff --git a/Gemfile b/Gemfile index a8bf18746..ac723d666 100644 --- a/Gemfile +++ b/Gemfile @@ -93,3 +93,7 @@ gem 'bulk_insert' gem 'searchkick' gem 'aasm' + +# oauth2 +gem 'omniauth', '~> 1.9.0' +gem 'omniauth-oauth2', '~> 1.6.0' diff --git a/Gemfile.lock b/Gemfile.lock index 9c80af8a9..1bf26bdf4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -110,7 +110,7 @@ GEM grape-entity (0.7.1) activesupport (>= 4.0) multi_json (>= 1.3.2) - hashie (3.6.0) + hashie (3.5.7) htmlentities (4.3.4) httparty (0.16.2) multi_xml (>= 0.5.2) @@ -164,6 +164,12 @@ GEM multi_json (~> 1.3) multi_xml (~> 0.5) rack (>= 1.2, < 3) + omniauth (1.9.0) + hashie (>= 3.4.6, < 3.7.0) + rack (>= 1.6.2, < 3) + omniauth-oauth2 (1.6.0) + oauth2 (~> 1.1) + omniauth (~> 1.9) pdfkit (0.8.4.1) public_suffix (3.0.2) puma (3.12.0) @@ -348,6 +354,8 @@ DEPENDENCIES listen (>= 3.0.5, < 3.2) mysql2 (>= 0.4.4, < 0.6.0) oauth2 + omniauth (~> 1.9.0) + omniauth-oauth2 (~> 1.6.0) pdfkit puma (~> 3.11) rack-cors diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index 2524c53d8..731a668bb 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -114,35 +114,6 @@ class AccountsController < ApplicationController end end - def successful_authentication(user) - uid_logger("Successful authentication start: '#{user.login}' from #{request.remote_ip} at #{Time.now.utc}") - # Valid user - self.logged_user = user - # generate a key and set cookie if autologin - - set_autologin_cookie(user) - UserAction.create(:action_id => user.try(:id), :action_type => "Login", :user_id => user.try(:id), :ip => request.remote_ip) - user.update_column(:last_login_on, Time.now) - # 注册完成后有一天的试用申请(先去掉) - # UserDayCertification.create(user_id: user.id, status: 1) - end - - def set_autologin_cookie(user) - token = Token.get_or_create_permanent_login_token(user, "autologin") - cookie_options = { - :value => token.value, - :expires => 1.month.from_now, - :path => '/', - :secure => false, - :httponly => true - } - if edu_setting('cookie_domain').present? - cookie_options = cookie_options.merge(domain: edu_setting('cookie_domain')) - end - cookies[autologin_cookie_name] = cookie_options - logger.info("cookies is #{cookies}") - end - def logout UserAction.create(action_id: User.current.id, action_type: "Logout", user_id: User.current.id, :ip => request.remote_ip) session[:user_id] = nil @@ -183,20 +154,6 @@ class AccountsController < ApplicationController end private - def autologin_cookie_name - edu_setting('autologin_cookie_name') || 'autologin' - end - - def logout_user - if User.current.logged? - if autologin = cookies.delete(autologin_cookie_name) - User.current.delete_autologin_token(autologin) - end - User.current.delete_session_token(session[:tk]) - self.logged_user = nil - end - session[:user_id] = nil - end # type 事件类型 1:用户注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验证手机号是否有效 # 如果有新的继续后面加 # login_type 1:手机类型 2:邮箱类型 diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index e7b4bdac6..d61aa32ac 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -7,6 +7,7 @@ class ApplicationController < ActionController::Base include ControllerRescueHandler include GitHelper include LoggerHelper + include LoginHelper protect_from_forgery prepend: true, unless: -> { request.format.json? } @@ -225,12 +226,6 @@ class ApplicationController < ActionController::Base # end end - def start_user_session(user) - session[:user_id] = user.id - session[:ctime] = Time.now.utc.to_i - session[:atime] = Time.now.utc.to_i - end - def user_setup # reacct静态资源加载不需要走这一步 return if params[:controller] == "main" @@ -256,17 +251,6 @@ class ApplicationController < ActionController::Base # User.current = User.find 81403 end - # Sets the logged in user - def logged_user=(user) - reset_session - if user && user.is_a?(User) - User.current = user - start_user_session(user) - else - User.current = User.anonymous - end - end - # Returns the current user or nil if no user is logged in # and starts a session if needed def find_current_user diff --git a/app/controllers/concerns/login_helper.rb b/app/controllers/concerns/login_helper.rb new file mode 100644 index 000000000..e79654958 --- /dev/null +++ b/app/controllers/concerns/login_helper.rb @@ -0,0 +1,69 @@ +module LoginHelper + extend ActiveSupport::Concern + + def edu_setting(name) + EduSetting.get(name) + end + + def autologin_cookie_name + edu_setting('autologin_cookie_name') || 'autologin' + end + + def set_autologin_cookie(user) + token = Token.get_or_create_permanent_login_token(user, "autologin") + cookie_options = { + :value => token.value, + :expires => 1.month.from_now, + :path => '/', + :secure => false, + :httponly => true + } + if edu_setting('cookie_domain').present? + cookie_options = cookie_options.merge(domain: edu_setting('cookie_domain')) + end + cookies[autologin_cookie_name] = cookie_options + Rails.logger.info("cookies is #{cookies}") + end + + def successful_authentication(user) + Rails.logger.info("id: #{user&.id} Successful authentication start: '#{user.login}' from #{request.remote_ip} at #{Time.now.utc}") + # Valid user + self.logged_user = user + + # generate a key and set cookie if autologin + set_autologin_cookie(user) + + UserAction.create(action_id: user&.id, action_type: 'Login', user_id: user&.id, ip: request.remote_ip) + user.update_column(:last_login_on, Time.now) + # 注册完成后有一天的试用申请(先去掉) + # UserDayCertification.create(user_id: user.id, status: 1) + end + + def logout_user + if User.current.logged? + if autologin = cookies.delete(autologin_cookie_name) + User.current.delete_autologin_token(autologin) + end + User.current.delete_session_token(session[:tk]) + self.logged_user = nil + end + session[:user_id] = nil + end + + # Sets the logged in user + def logged_user=(user) + reset_session + if user && user.is_a?(User) + User.current = user + start_user_session(user) + else + User.current = User.anonymous + end + end + + def start_user_session(user) + session[:user_id] = user.id + session[:ctime] = Time.now.utc.to_i + session[:atime] = Time.now.utc.to_i + end +end \ No newline at end of file diff --git a/app/controllers/oauth/base_controller.rb b/app/controllers/oauth/base_controller.rb new file mode 100644 index 000000000..e2eb26a2a --- /dev/null +++ b/app/controllers/oauth/base_controller.rb @@ -0,0 +1,20 @@ +class Oauth::BaseController < ActionController::Base + include RenderHelper + include LoginHelper + + skip_before_action :verify_authenticity_token + + private + + def session_user_id + session[:user_id] + end + + def current_user + @_current_user ||= User.find_by(id: session_user_id) + end + + def auth_hash + request.env['omniauth.auth'] + end +end \ No newline at end of file diff --git a/app/controllers/oauth/qq_controller.rb b/app/controllers/oauth/qq_controller.rb new file mode 100644 index 000000000..27ae3d8aa --- /dev/null +++ b/app/controllers/oauth/qq_controller.rb @@ -0,0 +1,9 @@ +class Oauth::QQController < Oauth::BaseController + def create + user = Oauth::CreateOrFindQqAccountService.call(current_user, auth_hash) + + successful_authentication(user) + + render_ok + end +end \ No newline at end of file diff --git a/app/controllers/oauth/wechat_controller.rb b/app/controllers/oauth/wechat_controller.rb new file mode 100644 index 000000000..8649e9b3f --- /dev/null +++ b/app/controllers/oauth/wechat_controller.rb @@ -0,0 +1,11 @@ +class WechatController < Oauth::BaseController + def create + user = Oauth::CreateOrFindWechatAccountService.call(current_user ,params) + + successful_authentication(user) + + render_ok + rescue Oauth::CreateOrFindWechatAccountService::Error => ex + render_error(ex.message) + end +end \ No newline at end of file diff --git a/app/libs/omniauth/strategies/qq.rb b/app/libs/omniauth/strategies/qq.rb new file mode 100644 index 000000000..513257e3c --- /dev/null +++ b/app/libs/omniauth/strategies/qq.rb @@ -0,0 +1,50 @@ +module OmniAuth + module Strategies + class QQ < OmniAuth::Strategies::OAuth2 + option :client_options, { + site: 'https://graph.qq.com', + authorize_url: '/oauth2.0/authorize', + token_url: '/oauth2.0/token' + } + + def request_phase + super + end + + def authorize_params + super.tap do |params| + %w[scope client_options].each do |v| + if request.params[v] + params[v.to_sym] = request.params[v] + end + end + end + end + + uid { raw_info['openid'].to_s } + + info do + { + name: user_info['nickname'], + nickname: user_info['nickname'], + image: user_info['figureurl_qq_1'] + } + end + + extra do + { 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) + end + end + end +end diff --git a/app/libs/wechat_oauth.rb b/app/libs/wechat_oauth.rb new file mode 100644 index 000000000..ba4baee30 --- /dev/null +++ b/app/libs/wechat_oauth.rb @@ -0,0 +1,13 @@ +module WechatOauth + class << self + attr_accessor :appid, :secret, :scope, :base_url + + def logger + @_logger ||= STDOUT + end + + def logger=(l) + @_logger = l + end + end +end \ No newline at end of file diff --git a/app/libs/wechat_oauth/error.rb b/app/libs/wechat_oauth/error.rb new file mode 100644 index 000000000..ac7f5fddc --- /dev/null +++ b/app/libs/wechat_oauth/error.rb @@ -0,0 +1,14 @@ +class WechatOauth::Error < StandardError + attr_reader :code + + def initialize(code, msg) + super(msg) + @code = code + end + + def message + I18n.t("oauth.wechat.#{code}") + rescue I18n::MissingTranslationData + super + end +end \ No newline at end of file diff --git a/app/libs/wechat_oauth/service.rb b/app/libs/wechat_oauth/service.rb new file mode 100644 index 000000000..35ef8f455 --- /dev/null +++ b/app/libs/wechat_oauth/service.rb @@ -0,0 +1,61 @@ +module WechatOauth::Service + module_function + + def request(method, url, params) + WechatOauth.logger.info("[WechatOauth] [#{method.to_s.upcase}] #{url} || #{params}") + + client = Faraday.new(url: WechatOauth.base_url) + response = client.public_send(method, url, params) + result = JSON.parse(response.body) + + WechatOauth.logger.info("[WechatOauth] [#{response.status}] #{result}") + + if result['errcode'].present? && result['errcode'].to_s != '0' + raise WechatOauth::Error.new(result['errcode'], result['errmsg']) + end + + result + end + + # https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html + # response: + # { + # "access_token":"ACCESS_TOKEN", + # "expires_in":7200, + # "refresh_token":"REFRESH_TOKEN", + # "openid":"OPENID", + # "scope":"SCOPE", + # "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" + # } + def access_token(code) + params = { + appid: WechatOauth.appid, + secret: WechatOauth.secret, + code: code, + grant_type: 'authorization_code' + } + + request(:get, '/sns/oauth2/access_token', params) + end + + # https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Authorized_Interface_Calling_UnionID.html + # response: + # { + # "openid":"OPENID", + # "nickname":"NICKNAME", + # "sex":1, + # "province":"PROVINCE", + # "city":"CITY", + # "country":"COUNTRY", + # "headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0", + # "privilege":[ + # "PRIVILEGE1", + # "PRIVILEGE2" + # ], + # "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" + # + # } + def user_info(access_token, openid) + request(:get, '/sns/userinfo', access_token: access_token, openid: openid) + end +end \ No newline at end of file diff --git a/app/models/open_user.rb b/app/models/open_user.rb new file mode 100644 index 000000000..cedf02edb --- /dev/null +++ b/app/models/open_user.rb @@ -0,0 +1,5 @@ +class OpenUser < ApplicationRecord + belongs_to :user + + validates :uid, presence: true, uniqueness: { scope: :type } +end \ No newline at end of file diff --git a/app/models/open_users/qq.rb b/app/models/open_users/qq.rb new file mode 100644 index 000000000..242693ce5 --- /dev/null +++ b/app/models/open_users/qq.rb @@ -0,0 +1,3 @@ +class OpenUsers::QQ < OpenUser + +end \ No newline at end of file diff --git a/app/models/open_users/wechat.rb b/app/models/open_users/wechat.rb new file mode 100644 index 000000000..046b3e086 --- /dev/null +++ b/app/models/open_users/wechat.rb @@ -0,0 +1,3 @@ +class OpenUsers::Wechat < OpenUser + +end \ No newline at end of file diff --git a/app/models/user.rb b/app/models/user.rb index 449a86e8b..9c9dea0ea 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -26,6 +26,8 @@ class User < ApplicationRecord MIX_PASSWORD_LIMIT = 8 + LOGIN_CHARS = %W(2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z).freeze + has_one :user_extension, dependent: :destroy accepts_nested_attributes_for :user_extension, update_only: true @@ -603,6 +605,15 @@ class User < ApplicationRecord admin? || business? end + def self.generate_login(prefix) + login = prefix + LOGIN_CHARS.sample(8).join('') + while User.exists?(login: login) + login = prefix + LOGIN_CHARS.sample(8).join('') + end + + login + end + protected def validate_password_length # 管理员的初始密码是5位 diff --git a/app/services/oauth/create_or_find_qq_account_service.rb b/app/services/oauth/create_or_find_qq_account_service.rb new file mode 100644 index 000000000..0eb187924 --- /dev/null +++ b/app/services/oauth/create_or_find_qq_account_service.rb @@ -0,0 +1,34 @@ +class Oauth::CreateOrFindQqAccountService < ApplicationService + + attr_reader :user, :params + + def initialize(user, params) + @user = user + @params = params + end + + def call + # 存在该用户 + open_user = OpenUsers::QQ.find_by(uid: params['uid']) + return open_user.user if open_user.present? + + if user.blank? || !user.logged? + # 新用户 + login = User.generate_login('q') + @user = User.new(login: login, nickname: params.dig('info', 'nickname')) + end + + ActiveRecord::Base.transaction do + if user.new_record? + user.save! + + gender = params.dig('extra', 'raw_info', 'gender') == '女' ? 1 : 0 + user.create_user_extension!(gender: gender) + end + + OpenUsers::QQ.create!(user: user, uid: params['uid']) + end + + user + end +end \ No newline at end of file diff --git a/app/services/oauth/create_or_find_wechat_account_service.rb b/app/services/oauth/create_or_find_wechat_account_service.rb new file mode 100644 index 000000000..b59d6a68d --- /dev/null +++ b/app/services/oauth/create_or_find_wechat_account_service.rb @@ -0,0 +1,48 @@ +class Oauth::CreateOrFindWechatAccountService < ApplicationService + Error = Class.new(StandardError) + + attr_reader :user, :params + + def initialize(user, params) + @user = user + @params = params + end + + def call + code = params['code'].to_s.strip + raise Error, 'Code不能为空' if code.blank? + + result = WechatOauth::Service.access_token(code) + + # 存在该用户 + open_user = OpenUsers::Wechat.find_by(uid: result['unionid']) + return open_user.user if open_user.present? + + if user.blank? || !user.logged? + # 新用户 + login = User.generate_login('w') + @user = User.new(login: login, nickname: result['nickname']) + end + + ActiveRecord::Base.transaction do + if user.new_record? + user.save! + + gender = result['sex'].to_i == 1 ? 0 : 1 + user.create_user_extension!(gender: gender) + end + + OpenUsers::Wechat.create!(user: user, uid: result['unionid']) + end + + user + rescue WechatOauth::Error => ex + raise Error, ex.message + end + + private + + def code + params[:code].to_s.strip + end +end \ No newline at end of file diff --git a/config/configuration.yml.example b/config/configuration.yml.example new file mode 100644 index 000000000..f492adb20 --- /dev/null +++ b/config/configuration.yml.example @@ -0,0 +1,19 @@ +defaults: &defaults + oauth: + qq: + appid: 'test' + secret: 'test123456' + wechat: + appid: 'test' + secret: 'test' + scope: 'snsapi_login' + base_url: 'https://api.weixin.qq.com' + +development: + <<: *defaults + +test: + <<: *defaults + +production: + <<: *defaults \ No newline at end of file diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb index d173fb9fa..a501cb14f 100644 --- a/config/initializers/inflections.rb +++ b/config/initializers/inflections.rb @@ -14,3 +14,8 @@ # ActiveSupport::Inflector.inflections(:en) do |inflect| # inflect.acronym 'RESTful' # end + +ActiveSupport::Inflector.inflections do |inflect| + inflect.acronym 'QQ' + inflect.acronym 'OmniAuth' +end \ No newline at end of file diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb new file mode 100644 index 000000000..27ade9ed4 --- /dev/null +++ b/config/initializers/omniauth.rb @@ -0,0 +1,17 @@ +OmniAuth.config.add_camelization 'qq', 'QQ' + +oauth_config = {} +begin + config = Rails.application.config_for(:configuration) + oauth_config = config.dig('oauth', 'qq') + raise 'oauth qq config missing' if oauth_config.blank? +rescue => ex + raise ex if Rails.env.production? + + puts %Q{\033[33m [warning] qq oauth config or configuration.yml missing, + please add it or execute 'cp config/configuration.yml.example config/configuration.yml' \033[0m} +end + +Rails.application.config.middleware.use OmniAuth::Builder do + provider :qq, oauth_config['appid'], oauth_config['secret'] +end diff --git a/config/initializers/wechat_oauth_init.rb b/config/initializers/wechat_oauth_init.rb new file mode 100644 index 000000000..6c7f849ec --- /dev/null +++ b/config/initializers/wechat_oauth_init.rb @@ -0,0 +1,17 @@ +oauth_config = {} +begin + config = Rails.application.config_for(:configuration) + oauth_config = config.dig('oauth', 'wechat') + raise 'oauth wechat config missing' if oauth_config.blank? +rescue => ex + raise ex if Rails.env.production? + + puts %Q{\033[33m [warning] wechat oauth config or configuration.yml missing, + please add it or execute 'cp config/configuration.yml.example config/configuration.yml' \033[0m} +end + +WechatOauth.appid = oauth_config['appid'] +WechatOauth.secret = oauth_config['secret'] +WechatOauth.scope = oauth_config['scope'] +WechatOauth.base_url = oauth_config['base_url'] +WechatOauth.logger = Rails.logger diff --git a/config/locales/oauth/wechat.zh-CN.yml b/config/locales/oauth/wechat.zh-CN.yml new file mode 100644 index 000000000..12b58c513 --- /dev/null +++ b/config/locales/oauth/wechat.zh-CN.yml @@ -0,0 +1,4 @@ +'zh-CN': + oauth: + wechat: + '40029': '授权已失效,请重新授权' \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 4e7b19687..46b6c1540 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -7,6 +7,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' + resources :edu_settings resources :admin scope '/api' do diff --git a/db/migrate/20190821054352_create_open_users.rb b/db/migrate/20190821054352_create_open_users.rb new file mode 100644 index 000000000..f8e0aba4b --- /dev/null +++ b/db/migrate/20190821054352_create_open_users.rb @@ -0,0 +1,14 @@ +class CreateOpenUsers < ActiveRecord::Migration[5.2] + def change + create_table :open_users do |t| + t.references :user + + t.string :type + t.string :uid + + t.timestamps + + t.index [:type, :uid], unique: true + end + end +end From 3805253fd681b5a4f72bc65b599e058d4c524152 Mon Sep 17 00:00:00 2001 From: p31729568 Date: Tue, 24 Sep 2019 14:25:57 +0800 Subject: [PATCH 002/252] fix merge --- app/models/user.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/models/user.rb b/app/models/user.rb index b9d9e48e6..e55bb8425 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -26,6 +26,8 @@ class User < ApplicationRecord MIX_PASSWORD_LIMIT = 8 + LOGIN_CHARS = %W(2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z).freeze + has_one :user_extension, dependent: :destroy accepts_nested_attributes_for :user_extension, update_only: true From 69f9390eeb65dcb2e80a6418e5ba83707b853b99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Fri, 11 Oct 2019 11:05:18 +0800 Subject: [PATCH 003/252] =?UTF-8?q?=E8=B0=83=E6=95=B4=E7=AB=8B=E5=8D=B3?= =?UTF-8?q?=E5=8F=91=E5=B8=83=20=E5=8C=85=E6=8B=AC=E5=8D=95=E4=B8=AA?= =?UTF-8?q?=E7=AB=8B=E5=8D=B3=E5=8F=91=E5=B8=83=E5=BC=B9=E7=AA=97=E5=B0=81?= =?UTF-8?q?=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coursesPublic/OneSelfOrderModal.js | 295 ++++++++++++++++++ .../graduation/tasks/GraduationTaskDetail.js | 15 +- .../modules/courses/graduation/tasks/index.js | 2 +- .../courses/shixunHomework/shixunHomework.js | 100 +++++- 4 files changed, 394 insertions(+), 18 deletions(-) create mode 100644 public/react/src/modules/courses/coursesPublic/OneSelfOrderModal.js diff --git a/public/react/src/modules/courses/coursesPublic/OneSelfOrderModal.js b/public/react/src/modules/courses/coursesPublic/OneSelfOrderModal.js new file mode 100644 index 000000000..87e823af6 --- /dev/null +++ b/public/react/src/modules/courses/coursesPublic/OneSelfOrderModal.js @@ -0,0 +1,295 @@ +import React,{ Component } from "react"; +import { Modal,Checkbox,DatePicker} from "antd"; +import { handleDateString } from 'educoder'; +import locale from 'antd/lib/date-picker/locale/zh_CN'; +import moment from 'moment'; +const CheckboxGroup = Checkbox.Group; +const dateFormat = 'YYYY-MM-DD HH:mm'; + +function range(start, end) { + const result = []; + for (let i = start; i < end; i++) { + result.push(i); + } + return result; +} +function disabledDateTime() { + return { + // disabledHours: () => range(0, 24).splice(4, 20), + disabledMinutes: () => range(1, 30).concat(range(31, 60)), + // disabledSeconds: () => [55, 56], + }; +} + + +function disabledDate(current) { + return current && current < moment().endOf('day').subtract(1, 'days'); +} + + + +class OneSelfOrderModal extends Component{ + constructor(props){ + super(props); + this.state={ + group_ids:[], + endtime:"" + } + } + componentDidMount() { + + + if(this.props.course_groups!=undefined&&this.props.course_groups.length!=0){ + + let arr=this.props.course_groups.map(item => item.id); + this.shixunhomeworkedit(arr); + } + + if(this.props.starttimes===undefined||this.props.starttimes===""||this.props.starttimes===null){ + this.setState({ + endtime:moment(moment(handleDateString(this.props.staytime)).add(1, 'months')).format("YYYY-MM-DD HH:mm") + }) + }else{ + this.setState({ + endtime:moment(handleDateString(this.props.starttimes)).format("YYYY-MM-DD HH:mm") + }) + } + } + componentDidUpdate=(prevProps)=>{ + // if(prevProps.visible!=this.props.visible){ + // + // if(this.props.course_groups!=undefined){ + // let arr=this.props.course_groups.map(item => item.id); + // this.shixunhomeworkedit(arr); + // } + // } + if(prevProps.course_groups!=this.props.course_groups){ + if(this.props.course_groups!=undefined){ + let arr=this.props.course_groups.map(item => item.id); + this.shixunhomeworkedit(arr); + } + } + if(prevProps.starttimes!=this.props.starttimes){ + + if(this.props.starttimes===undefined||this.props.starttimes===""||this.props.starttimes===null){ + this.setState({ + endtime:moment(moment(handleDateString(this.props.staytime)).add(1, 'months')).format("YYYY-MM-DD HH:mm") + }) + }else{ + this.setState({ + endtime:moment(handleDateString(this.props.starttimes)).format("YYYY-MM-DD HH:mm") + }) + } + } + } + + //勾选实训 + shixunhomeworkedit=(list)=>{ + + this.setState({ + group_ids:list + }) + this.props.getcourse_groupslist && this.props.getcourse_groupslist(list) + } + + onChangeTimeend= (date, dateString) => { + // console.log('startValue',dateString); + + this.setState({ + endtime: date===null?"":handleDateString(dateString), + }) + + } + + propsSaves=(ds,endtime)=>{ + + if(ds.length ===0&&endtime === ""){ + this.props.Saves() + }else{ + if(this.props.typs!="end"){ + if(endtime === ""||endtime===undefined||endtime===null){ + + this.setState({ + endtimetype:true, + endtimetypevalue:"截止时间不能为空" + }) + return + } + + if(moment(endtime,"YYYY-MM-DD HH:mm") <= moment(this.props.starttimes,"YYYY-MM-DD HH:mm")){ + this.setState({ + endtimetype:true, + endtimetypevalue:"必须晚于发布时间" + }) + return + } + } + this.props.Saves(ds,moment(handleDateString(endtime),"YYYY-MM-DD HH:mm").format("YYYY-MM-DD HH:mm")) + } + + + } + + render(){ + let {group_ids,endtime}=this.state; + let {course_groups}=this.props; + + // console.log(this.props.starttimes) + // console.log(endtime) + // console.log(this.props.starttimes) + // console.log(this.state.endtime) + + // console.log(this.props.starttime,this.props.endtime) + // TODO course_groups为空时的处理 + + // let endtimelist=this.props.starttimes===undefined||this.props.starttimes===""?"":moment(handleDateString(endtime)).add(1,'months') + return( +
+ { + this.props.OneSelftype===true?:"" + } + { + this.props.OneSelftype===true? +
+ + + { this.props.usingCheckBeforePost ? + +

+ 发布设置均可修改, + + 点击修改 + +

+

+ 此设置将对所有分班生效 +

+
: + +

+ {this.props.Topval} + {this.props.Topvalright} +

+

+ {this.props.Botvalleft===undefined?"":"{this.props.Botvalleft}"} + {this.props.Botval} +

+
} + + + {this.props.starttime===undefined|| + this.props.starttime===""?"" + :

+ + 发布时间: + {this.props.starttime} + + {/*{this.props.endtime}*/} + 截止时间: + + {this.state.endtimetype===true?

{this.state.endtimetypevalue}
:""} + +

} + {/* usingCheckBeforePost 为true的时候 全选所有分班 */} + {this.props.modaltype===undefined||this.props.modaltype===2||this.props.modaltype===4 + || !course_groups || course_groups.length == 0 + || this.props.usingCheckBeforePost ?"":
    + + {/**/} + {/**/} + { + { + course_groups.map((item,key)=>{ + return( +
    +
  • + + {item.name} + + +
  • + +
    + ) + }) + } +
    } + +
+ } + + + +
+
:""} +
+ ) + } +} +export default OneSelfOrderModal; \ No newline at end of file diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTaskDetail.js b/public/react/src/modules/courses/graduation/tasks/GraduationTaskDetail.js index b9830d1fc..fbbfafabc 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTaskDetail.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTaskDetail.js @@ -7,6 +7,7 @@ import Loading from '../../../../Loading'; import {BrowserRouter as Router,Route,Switch} from 'react-router-dom'; import axios from 'axios'; import HomeworkModal from "../../coursesPublic/HomeworkModal"; +import OneSelfOrderModal from "../../coursesPublic/OneSelfOrderModal"; import AccessoryModal from "../../coursesPublic/AccessoryModal"; import Associationmodel from '../../coursesPublic/Associationmodel'; import CoursesListType from '../../coursesPublic/CoursesListType'; @@ -40,6 +41,7 @@ class GraduationTaskDetail extends Component{ this.state={ modalname:undefined, visible:false, + OneSelftype:false, Topval:undefined, starttime:undefined, starttimes:undefined, @@ -115,17 +117,20 @@ class GraduationTaskDetail extends Component{ } //立即发布 publish=()=>{ + let {questionslist}=this.state; let starttime= this.props.getNowFormatDates(1,1); let endtime=this.props.getNowFormatDates(2,1); // this.homeworkstart() this.setState({ modalname:"立即发布", visible:true, + OneSelftype:true, Topval:"学生将立即收到毕设任务", // Botvalleft:"点击修改", // Botval:`本操作只对"未发布"的分班有效`, starttime:moment(moment(new Date())).format("YYYY-MM-DD HH:mm") , - starttimes:this.props.getNowFormatDates(1), + starttimes:questionslist.end_time, + staytime:this.props.getNowFormatDates(1), typs:"start", endtime:endtime, Cancelname:"暂不发布", @@ -176,7 +181,9 @@ class GraduationTaskDetail extends Component{ this.setState({ modalname:"立即截止", visible:true, + OneSelftype:true, Topval:"学生将不能再提交作品", + starttime:undefined, // Botvalleft:"暂不截止", // Botval:`本操作只对"提交中"的分班有效`, Cancelname:"暂不截止", @@ -212,6 +219,7 @@ class GraduationTaskDetail extends Component{ Modalstype:false, Loadtype:false, visible:false, + OneSelftype:false, Modulationtype:false, Allocationtype:false, Modalstopval:"", @@ -321,11 +329,12 @@ class GraduationTaskDetail extends Component{ { questionslist &&
- { + let selectnum= this.testonSelect(); + if(selectnum===true){ + this.noSelect(); + return + } + let coursesId=this.props.match.params.coursesId; + let url="/courses/"+coursesId+"/all_course_groups.json"; + + axios.get(url).then((response) => { + + if(response.status===200){ + let starttime= this.props.getNowFormatDates(1); + let endtime=this.props.getNowFormatDates(2); + this.setState({ + modalname:"立即发布", + modaltype:response.data.course_groups===null||response.data.course_groups.length===0?2:1, + OneSelftype:true, + typs:"start", + Topval:"学生将立即收到作业", + // Botvalleft:"暂不发布", + Botval:`本操作只对"未发布"的分班有效`, + starttime:"发布时间:"+moment(moment(new Date())).format("YYYY-MM-DD HH:mm"), + starttimes:starttime, + endtime:"截止时间:"+endtime, + Cancelname:"暂不发布", + Savesname:"立即发布", + Cancel:this.homeworkhide, + Saves:this.homeworkstartend, + course_groups:response.data.course_groups, + }) + } + }).catch((error) => { + console.log(error) + }); + + } + + cancelmodels=()=>{ this.setState({ Modalstype:false, @@ -316,10 +360,12 @@ class ShixunHomework extends Component{ }) } - this.props.showNotification(result.data.message) + + this.homeworkupdatalist(Coursename,page,order); + this.cancelmodel() + this.props.showNotification(result.data.message) this.props.updataleftNavfun() - this.homeworkupdatalist(Coursename,page,order); - this.cancelmodel() + } }).catch((error)=>{ console.log(error); @@ -414,11 +460,11 @@ class ShixunHomework extends Component{ Loadtype:false, course_groups:[] }) - + this.homeworkupdatalist(Coursename,page,order); + this.cancelmodel() this.props.showNotification(response.data.message) this.props.updataleftNavfun() - this.homeworkupdatalist(Coursename,page,order); - this.cancelmodel() + } }) .catch(function (error) { @@ -722,8 +768,8 @@ class ShixunHomework extends Component{ checkedtype:false, antIcon:false }) + this.homeworkupdatalist(Coursename,page,order); this.props.showNotification(response.data.message) - this.homeworkupdatalist(Coursename,page,order); this.props.updataleftNavfun() }else{ this.setState({ @@ -782,6 +828,7 @@ class ShixunHomework extends Component{ this.setState({ Modalstype:false, + OneSelftype:false, Loadtype:false, visible:false, Modalstopval:"", @@ -834,9 +881,10 @@ class ShixunHomework extends Component{ Loadtype:false, checkBoxValues:[] }) + this.homeworkupdatalist(Coursename,page,order); this.props.showNotification(response.data.message) - this.homeworkupdatalist(Coursename,page,order); + } }) .catch(function (error) { @@ -886,9 +934,10 @@ class ShixunHomework extends Component{ checkBoxValues:[], checkAllValue:false }) + this.homeworkupdatalist(Coursename,page,order); this.props.showNotification('已完成') this.props.updataleftNavfun() - this.homeworkupdatalist(Coursename,page,order); + } }) } @@ -1022,7 +1071,7 @@ class ShixunHomework extends Component{ loadtype={this.state.Loadtype} antIcon={this.state.antIcon} />:""} - {/*立即发布*/} + {/*批量立即发布*/} {visible===true?this.getcourse_groupslist(id)} />:""} - + {/*{单个立即发布}*/} + {/*this.getcourse_groupslist(id)}*/} + {/*/>*/} {shixunmodal===true||shixunpath===true? + { isAdmin && +
  • + 导出 + +
  • + } + + } + secondRowLeft={ + total_count ? : '' + } + onPressEnter={onPressEnter} + > + + ) +} +export default CourseGroupList \ No newline at end of file From e4ec0cc0a278ff8e79374119e0a259dd799be420 Mon Sep 17 00:00:00 2001 From: hjm <63528605@qq.com> Date: Fri, 11 Oct 2019 15:25:17 +0800 Subject: [PATCH 006/252] list --- .../courses/members/CourseGroupList.js | 43 +++++++++++-------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/public/react/src/modules/courses/members/CourseGroupList.js b/public/react/src/modules/courses/members/CourseGroupList.js index 26a1abda3..15bc12bd8 100644 --- a/public/react/src/modules/courses/members/CourseGroupList.js +++ b/public/react/src/modules/courses/members/CourseGroupList.js @@ -24,15 +24,27 @@ import ChangeRolePop from './ChangeRolePop' 角色数组, CREATOR: 创建者, PROFESSOR: 教师, ASSISTANT_PROFESSOR: 助教, STUDENT: 学生 */ function CourseGroupList(props) { - const [checkBoxRoles, setCheckBoxRoles] = useState() + const [serachValue, setSerachValue] = useState('') + + const [DownloadType, setDownloadType] = useState() + const [DownloadMessageval, setDownloadMessageval] = useState() + + const [listRes, setListRes] = useState({}) const courseId = props.match.params.coursesId useEffect(() => { fetchAll() }, []) - function fetchAll() { + async function fetchAll() { const url = `/courses/${courseId}/course_groups.json` + const response = await axios.get(url, params: { + search: searchValue + }); + console.log(response) + if (response) { + setListRes(response.data) + } } const onConfirm = async () => { } @@ -52,8 +64,8 @@ function CourseGroupList(props) { function onInputSearchChange() { } - function onInputSearchChange() { - + function onInputSearchChange(e) { + setSerachValue(e.target.value) } function Downloadcal() { @@ -67,18 +79,13 @@ function CourseGroupList(props) { }else if(response.data.status&&response.data.status===-2){ if(response.data.message === "100"){ - // 已超出文件导出的上限数量(100 ),建议: - - this.setState({ - DownloadType:true, - DownloadMessageval:100 - }) + // 已超出文件导出的上限数量(100 ),建议: + setDownloadType(true) + setDownloadMessageval(100) }else { - //因附件资料超过500M - this.setState({ - DownloadType:true, - DownloadMessageval:500 - }) + //因附件资料超过500M + setDownloadType(true) + setDownloadMessageval(500) } }else { props.slowDownload(url) @@ -97,7 +104,9 @@ function CourseGroupList(props) { const DownloadMessageval= ''; const DownloadType= ''; - const total_count = 9 + const total_count = listRes.group_count; + const none_group_member_count = listRes.none_group_member_count; + const course_groups = listRes.course_groups let exportUrl = `/courses/${courseId}/export_member_scores_excel.xlsx?`; //总成绩 let exportUrltwo = `/courses/${courseId}/export_couser_info.xlsx?`; //课堂信息 @@ -115,7 +124,7 @@ function CourseGroupList(props) { searchValue={ searchValue } onInputSearchChange={onInputSearchChange} showSearchInput={total_count >= 10} - searchPlaceholder={ '请输入姓名、学号进行搜索' } + searchPlaceholder={ '请输入名称进行搜索' } firstRowRight={ { // pageType !== TYPE_STUDENTS && From 7d6658f72d2adaa454e9bf01f5f1e17efdd8175c Mon Sep 17 00:00:00 2001 From: hjm <63528605@qq.com> Date: Fri, 11 Oct 2019 15:51:26 +0800 Subject: [PATCH 007/252] table --- .../courses/members/CourseGroupList.js | 13 +- .../courses/members/CourseGroupListTable.js | 117 ++++++++++++++++++ 2 files changed, 126 insertions(+), 4 deletions(-) create mode 100644 public/react/src/modules/courses/members/CourseGroupListTable.js diff --git a/public/react/src/modules/courses/members/CourseGroupList.js b/public/react/src/modules/courses/members/CourseGroupList.js index 15bc12bd8..248a4d52d 100644 --- a/public/react/src/modules/courses/members/CourseGroupList.js +++ b/public/react/src/modules/courses/members/CourseGroupList.js @@ -20,6 +20,7 @@ import NoneData from "../coursesPublic/NoneData" import DownloadMessageysl from "../../modals/DownloadMessageysl"; import CreateGroupByImportModal from './modal/CreateGroupByImportModal' import ChangeRolePop from './ChangeRolePop' +import CourseGroupListTable from './CourseGroupListTable' /** 角色数组, CREATOR: 创建者, PROFESSOR: 教师, ASSISTANT_PROFESSOR: 助教, STUDENT: 学生 */ @@ -38,9 +39,9 @@ function CourseGroupList(props) { }, []) async function fetchAll() { const url = `/courses/${courseId}/course_groups.json` - const response = await axios.get(url, params: { + const response = await axios.get(url, { params: { search: searchValue - }); + }}); console.log(response) if (response) { setListRes(response.data) @@ -102,8 +103,7 @@ function CourseGroupList(props) { const isCourseEnd= ''; const course_group_id= ''; - const DownloadMessageval= ''; - const DownloadType= ''; + const total_count = listRes.group_count; const none_group_member_count = listRes.none_group_member_count; const course_groups = listRes.course_groups @@ -192,6 +192,11 @@ function CourseGroupList(props) { } onPressEnter={onPressEnter} > + + ) } diff --git a/public/react/src/modules/courses/members/CourseGroupListTable.js b/public/react/src/modules/courses/members/CourseGroupListTable.js new file mode 100644 index 000000000..96a13cf27 --- /dev/null +++ b/public/react/src/modules/courses/members/CourseGroupListTable.js @@ -0,0 +1,117 @@ +import React, { useState, useEffect } from 'react' + +import { Input,Checkbox,Table, Pagination, Modal,Menu ,Spin, Tooltip , Divider, Popconfirm } from "antd"; + +import { WordsBtn, trigger, on, off, getUrl, downloadFile , sortDirections } from 'educoder' +/** + 角色数组, CREATOR: 创建者, PROFESSOR: 教师, ASSISTANT_PROFESSOR: 助教, STUDENT: 学生 + course_members_count: 0 + id: 2441 + invite_code: "WUNX9K" + member_manager: "全部教师" + name: "e'e'e" +*/ +function buildColumns() { + const columns=[{ + title: '序号', + dataIndex: 'id', + key: 'id', + align:'center', + width:"10%", + className:"color-grey-6", + render: (id, record, index) => { + return index + 1 + } + }, + { + title: '分班名称', + dataIndex: 'name', + key: 'name', + align:'center', + width:"20%", + className:"color-grey-6", + render: (name, record, index) => { + return name + } + }, + { + title: '邀请码', + dataIndex: 'invite_code', + key: 'invite_code', + align:'center', + width:"10%", + className:"color-grey-6", + render: (invite_code, record, index) => { + return invite_code + } + }, + { + title: '学生成员', + dataIndex: 'course_members_count', + key: 'course_members_count', + align:'center', + width:"10%", + className:"color-grey-6", + render: (course_members_count, record, index) => { + return course_members_count + } + }, + { + title: '管理教师', + dataIndex: 'member_manager', + key: 'member_manager', + align:'center', + width:"25%", + className:"color-grey-6", + render: (member_manager, record, index) => { + return member_manager + } + }, + { + title: '操作', + dataIndex: 'setting', + key: 'setting', + align:'center', + width:"25%", + className:"color-grey-6", + render: (none, record, index) => { + return + } + }, + ] + return columns +} +function CourseGroupListTable(props) { + const [serachValue, setSerachValue] = useState('') + + const courseId = props.match.params.coursesId + + useEffect(() => { + + }, []) + + const onConfirm = async () => { + } + + function deleteDir() { + + } + const isAdmin = true; + const isSuperAdmin = true; + const isParent = true; + const searchValue = ''; + const isCourseEnd= ''; + const course_group_id= ''; + + + const course_groups = props.course_groups + const columns = buildColumns() + return ( + + {/* onChange={onTableChange} */} +
    + +
    + ) +} +export default CourseGroupListTable \ No newline at end of file From 535e1643b53e0ad2be90bed8822b5c7489a9f96a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Fri, 11 Oct 2019 16:02:28 +0800 Subject: [PATCH 008/252] =?UTF-8?q?=E7=AB=8B=E5=8D=B3=E5=8F=91=E5=B8=83?= =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/AppConfig.js | 4 +- .../coursesPublic/OneSelfOrderModal.js | 43 +++++++++++++------ 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/public/react/src/AppConfig.js b/public/react/src/AppConfig.js index c00c5fb62..e1d5da561 100644 --- a/public/react/src/AppConfig.js +++ b/public/react/src/AppConfig.js @@ -84,9 +84,9 @@ export function initAxiosInterceptors(props) { } config.url = `${proxy}${url}`; if (config.url.indexOf('?') == -1) { - config.url = `${config.url}?debug=${'student'}`; + config.url = `${config.url}?debug=${debugType}`; } else { - config.url = `${config.url}&debug=${'student'}`; + config.url = `${config.url}&debug=${debugType}`; } } else { // 加api前缀 diff --git a/public/react/src/modules/courses/coursesPublic/OneSelfOrderModal.js b/public/react/src/modules/courses/coursesPublic/OneSelfOrderModal.js index 35f7ca46f..d706bf2ee 100644 --- a/public/react/src/modules/courses/coursesPublic/OneSelfOrderModal.js +++ b/public/react/src/modules/courses/coursesPublic/OneSelfOrderModal.js @@ -221,27 +221,44 @@ class OneSelfOrderModal extends Component{ :""}

    } {/* usingCheckBeforePost 为true的时候 全选所有分班 */} - {this.props.modaltype===undefined||this.props.modaltype===2 - || this.props.usingCheckBeforePost ?"":
    -
      + {weixinlogin===true?"":
      • {this.enter(0)}}>登录
      • {/*
      • {this.register(0)}}>快捷登录
      • */} -
      +
    }
    -
    + {weixinlogin===true?"":
    {/*快捷登录*/} diff --git a/public/react/src/modules/user/LoginRegisterComponent.js b/public/react/src/modules/user/LoginRegisterComponent.js index 8b7df2e02..476e4cf25 100644 --- a/public/react/src/modules/user/LoginRegisterComponent.js +++ b/public/react/src/modules/user/LoginRegisterComponent.js @@ -890,7 +890,9 @@ class LoginRegisterComponent extends Component { console.log(classpass); return ( -
    +
    - + {weixinlogin===false? 登录 注册 - + :""} - { - parseInt(tab[0])==0 && + { + weixinlogin===false&&parseInt(tab[0])==0 &&
    + +
    +
    +
    +
    + +
    +
    + 为了更好的为您服务,请关联一个EduCoder账号 +
    +
    + +
    + +

    + + +

    + 新用户 +
    + + +
    欢迎来到EduCoder,新用户登录EduCoder可以到“账号管理-安全设置”中绑定手机/邮箱,以后可以用绑定的手机/邮箱,设置的密码登录EduCoder了。
    + 立即体验表示您已经同意我们的 服务协议条款 +
    + +
    +
    + +

    + +

    + + +

    + 老用户 +
    + + +
    已有EduCoder账号,可以输入您的账号和密码,将您的微信账号与EduCoder账号进行绑定。
    + + + + + + + {this.state.logintypes==="username"?请填写账号:this.state.logintypes==="password"?请填写密码:""} +
    + +
    +
    + +

    +
    + +
    +
    +
    © 2019 EduCoder湘ICP备17009477号Trustie   &   IntelliDE inside.
    +
    +
    + +
    + ) + } + +} + +export default Otherlogin; diff --git a/public/react/src/modules/user/LoginRegisterComponent.js b/public/react/src/modules/user/LoginRegisterComponent.js index 022564f5b..1e71ed681 100644 --- a/public/react/src/modules/user/LoginRegisterComponent.js +++ b/public/react/src/modules/user/LoginRegisterComponent.js @@ -1163,7 +1163,7 @@ class LoginRegisterComponent extends Component { color: '#676767', }}>我已阅读并同意 - 《服务协议条款》 + 《服务协议条款》 @@ -1184,7 +1184,7 @@ class LoginRegisterComponent extends Component { frameBorder="0" sandbox="allow-scripts allow-same-origin allow-top-navigation" scrolling="no" - src="https://open.weixin.qq.com/connect/qrconnect?appid=wx6b119e2d829c13fa&redirect_uri=https%3a%2f%2fwww.educoder.net%2f&response_type=code&scope=snsapi_login#wechat_redirect">:""} + src="https://open.weixin.qq.com/connect/qrconnect?appid=wx6b119e2d829c13fa&redirect_uri=https%3a%2f%2fwww.educoder.net%2fotherlogin&response_type=code&scope=snsapi_login#wechat_redirect">:""} {weixinlogin===true?

    this.hideweixinlogin()}>返回登录注册

    :""} From 358c718f7e5a7f8e8dfa5d63ebc35edea7c2eb7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Sat, 12 Oct 2019 16:22:28 +0800 Subject: [PATCH 044/252] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/modules/courses/shixunHomework/ShixunStudentWork.js | 1 + .../src/modules/courses/shixunHomework/Workquestionandanswer.js | 1 + 2 files changed, 2 insertions(+) diff --git a/public/react/src/modules/courses/shixunHomework/ShixunStudentWork.js b/public/react/src/modules/courses/shixunHomework/ShixunStudentWork.js index 074bab663..e7f3ae5c7 100644 --- a/public/react/src/modules/courses/shixunHomework/ShixunStudentWork.js +++ b/public/react/src/modules/courses/shixunHomework/ShixunStudentWork.js @@ -416,6 +416,7 @@ class ShixunStudentWork extends Component { axios.get(url).then((response) => { if(response.status===200){ + const dataformat = 'YYYY-MM-DD HH:mm'; let starttime= this.props.getNowFormatDates(1); let endtime=this.props.getNowFormatDates(2); this.setState({ diff --git a/public/react/src/modules/courses/shixunHomework/Workquestionandanswer.js b/public/react/src/modules/courses/shixunHomework/Workquestionandanswer.js index 57a51241e..f211b4a1d 100644 --- a/public/react/src/modules/courses/shixunHomework/Workquestionandanswer.js +++ b/public/react/src/modules/courses/shixunHomework/Workquestionandanswer.js @@ -157,6 +157,7 @@ class Workquestionandanswer extends Component { axios.get(url).then((response) => { if (response.status === 200) { + const dataformat = 'YYYY-MM-DD HH:mm'; let starttime = this.props.getNowFormatDates(1); let endtime = this.props.getNowFormatDates(2); this.setState({ From ce511202fbc01cc046cff3cf9d173e49e190503b Mon Sep 17 00:00:00 2001 From: p31729568 Date: Sat, 12 Oct 2019 16:31:13 +0800 Subject: [PATCH 045/252] fix oauth user bug --- app/services/oauth/create_or_find_qq_account_service.rb | 2 +- app/services/oauth/create_or_find_wechat_account_service.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 3b3c71367..691764ea2 100644 --- a/app/services/oauth/create_or_find_qq_account_service.rb +++ b/app/services/oauth/create_or_find_qq_account_service.rb @@ -17,7 +17,7 @@ class Oauth::CreateOrFindQqAccountService < ApplicationService new_user = true # 新用户 login = User.generate_login('q') - @user = User.new(login: login, nickname: params.dig('info', 'nickname')) + @user = User.new(login: login, nickname: params.dig('info', 'nickname'), type: 'User', status: User::STATUS_ACTIVE) end ActiveRecord::Base.transaction do diff --git a/app/services/oauth/create_or_find_wechat_account_service.rb b/app/services/oauth/create_or_find_wechat_account_service.rb index 717f4bbd4..0313054b7 100644 --- a/app/services/oauth/create_or_find_wechat_account_service.rb +++ b/app/services/oauth/create_or_find_wechat_account_service.rb @@ -24,7 +24,7 @@ class Oauth::CreateOrFindWechatAccountService < ApplicationService new_user = true # 新用户 login = User.generate_login('w') - @user = User.new(login: login, nickname: result['nickname']) + @user = User.new(login: login, nickname: result['nickname'], type: 'User', status: User::STATUS_ACTIVE) end ActiveRecord::Base.transaction do From a03bb0dafb33612f29bac101e74b5cab9d2de127 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Sat, 12 Oct 2019 16:35:31 +0800 Subject: [PATCH 046/252] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E7=99=BB=E5=BD=95=20?= =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/App.js | 9 ++++ public/react/src/modules/login/LoginDialog.js | 2 +- public/react/src/modules/login/Otherlogin.js | 44 ++++------------ .../src/modules/login/Otherloginstart.js | 52 +++++++++++++++++++ .../modules/user/LoginRegisterComponent.js | 2 +- 5 files changed, 74 insertions(+), 35 deletions(-) create mode 100644 public/react/src/modules/login/Otherloginstart.js diff --git a/public/react/src/App.js b/public/react/src/App.js index f9b6fd36b..34b5d1a4f 100644 --- a/public/react/src/App.js +++ b/public/react/src/App.js @@ -70,6 +70,12 @@ const Otherlogin=Loadable({ loader: () => import('./modules/login/Otherlogin'), loading: Loading, }) + +const Otherloginstart=Loadable({ + loader: () => import('./modules/login/Otherloginstart'), + loading: Loading, +}) + const TestIndex = Loadable({ loader: () => import('./modules/test'), loading: Loading, @@ -412,6 +418,9 @@ class App extends Component { + diff --git a/public/react/src/modules/login/LoginDialog.js b/public/react/src/modules/login/LoginDialog.js index b0c1602a9..ae7d781e9 100644 --- a/public/react/src/modules/login/LoginDialog.js +++ b/public/react/src/modules/login/LoginDialog.js @@ -638,7 +638,7 @@ class LoginDialog extends Component { frameBorder="0" sandbox="allow-scripts allow-same-origin allow-top-navigation" scrolling="no" - src="https://open.weixin.qq.com/connect/qrconnect?appid=wx6b119e2d829c13fa&redirect_uri=https%3a%2f%2fwww.educoder.net%2fotherlogin&response_type=code&scope=snsapi_login#wechat_redirect">:""} + src="https://open.weixin.qq.com/connect/qrconnect?appid=wx6b119e2d829c13fa&redirect_uri=https%3a%2f%2fwww.educoder.net%2fotherloginstart&response_type=code&scope=snsapi_login#wechat_redirect">:""} {weixinlogin===true?

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

    :""} diff --git a/public/react/src/modules/login/Otherlogin.js b/public/react/src/modules/login/Otherlogin.js index 2dc82b578..3c27e0e96 100644 --- a/public/react/src/modules/login/Otherlogin.js +++ b/public/react/src/modules/login/Otherlogin.js @@ -79,48 +79,26 @@ class Otherlogin extends Component { } - getinfo=()=>{ - let url = `/users/get_user_info.json` - axios.get(url).then((result)=> { - console.log(result); - if(result){ - this.setState({ - data:result.data, - spinnings:false - }) - } - }).catch((error)=>{ - this.setState({ - spinnings:false - }) - }) - - } componentDidMount() { - let query=this.props.location.search; - 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)=> { + + let url = `/users/get_user_info.json` + axios.get(url).then((result)=> { + console.log(result); if(result){ - if(result.data.status===0){ - if(result.data.true===false){ - this.getinfo() - }else{ - // this.getinfo() - window.location.href="/" - } - } + this.setState({ + data:result.data, + spinnings:false + }) } }).catch((error)=>{ this.setState({ spinnings:false }) }) - } + + + } loginInputonChange=(e)=>{ diff --git a/public/react/src/modules/login/Otherloginstart.js b/public/react/src/modules/login/Otherloginstart.js new file mode 100644 index 000000000..4b134805d --- /dev/null +++ b/public/react/src/modules/login/Otherloginstart.js @@ -0,0 +1,52 @@ +import React, { Component } from 'react'; + +import { BrowserRouter as Router, Route, Link } from "react-router-dom"; + +import { Spin } from 'antd'; +import axios from 'axios'; +class Otherloginstart extends Component { + + componentDidMount() { + let query=this.props.location.search; + 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.true===false){ + window.location.href="/otherlogin" + }else{ + // this.getinfo() + window.location.href="/" + } + } + } + }).catch((error)=>{ + + }) + + } + + render() { + // Loading + return ( +
    + + +
    + ); + } +} + +export default Otherloginstart; \ No newline at end of file diff --git a/public/react/src/modules/user/LoginRegisterComponent.js b/public/react/src/modules/user/LoginRegisterComponent.js index a599bcf24..fedc3cb22 100644 --- a/public/react/src/modules/user/LoginRegisterComponent.js +++ b/public/react/src/modules/user/LoginRegisterComponent.js @@ -1192,7 +1192,7 @@ class LoginRegisterComponent extends Component { frameBorder="0" sandbox="allow-scripts allow-same-origin allow-top-navigation" scrolling="no" - src="https://open.weixin.qq.com/connect/qrconnect?appid=wx6b119e2d829c13fa&redirect_uri=https%3a%2f%2fwww.educoder.net%2fotherlogin&response_type=code&scope=snsapi_login#wechat_redirect">:""} + src="https://open.weixin.qq.com/connect/qrconnect?appid=wx6b119e2d829c13fa&redirect_uri=https%3a%2f%2fwww.educoder.net%2fotherloginstart&response_type=code&scope=snsapi_login#wechat_redirect">:""} {weixinlogin===true?

    this.hideweixinlogin()}>返回登录注册

    :""} From 076d09bc9b350c2f43121ba2bbe440b58af11c57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Sat, 12 Oct 2019 16:42:54 +0800 Subject: [PATCH 047/252] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/modules/courses/shixunHomework/Listofworksstudentone.js | 2 +- .../src/modules/courses/shixunHomework/ShixunStudentWork.js | 2 +- .../src/modules/courses/shixunHomework/Trainingjobsetting.js | 2 +- .../src/modules/courses/shixunHomework/Workquestionandanswer.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js b/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js index 6de412525..926e1b023 100644 --- a/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js +++ b/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js @@ -2803,7 +2803,7 @@ class Listofworksstudentone extends Component { starttime: "发布时间:" + moment(moment(new Date())).format("YYYY-MM-DD HH:mm"), endtime: "截止时间:" + endtime, starttimes:starttime, - starttimesend:response.data.end_time===undefined||response.data.end_time===null||response.data.end_time===""?undefined:moment(response.data.end_time, dataformat), + starttimesend:response.data.end_time===undefined||response.data.end_time===null||response.data.end_time===""?undefined:response.data.end_time, typs:"start", Cancelname: "暂不发布", Savesname: "立即发布", diff --git a/public/react/src/modules/courses/shixunHomework/ShixunStudentWork.js b/public/react/src/modules/courses/shixunHomework/ShixunStudentWork.js index e7f3ae5c7..95de82445 100644 --- a/public/react/src/modules/courses/shixunHomework/ShixunStudentWork.js +++ b/public/react/src/modules/courses/shixunHomework/ShixunStudentWork.js @@ -434,7 +434,7 @@ class ShixunStudentWork extends Component { Saves:this.homeworkstartend, course_groups:response.data.course_groups, starttimes:starttime, - starttimesend:response.data.end_time===undefined||response.data.end_time===null||response.data.end_time===""?undefined:moment(response.data.end_time, dataformat), + starttimesend:response.data.end_time===undefined||response.data.end_time===null||response.data.end_time===""?undefined:response.data.end_time, typs:"start", }) } diff --git a/public/react/src/modules/courses/shixunHomework/Trainingjobsetting.js b/public/react/src/modules/courses/shixunHomework/Trainingjobsetting.js index 5cf7b4f8b..5d2462ec0 100644 --- a/public/react/src/modules/courses/shixunHomework/Trainingjobsetting.js +++ b/public/react/src/modules/courses/shixunHomework/Trainingjobsetting.js @@ -1537,7 +1537,7 @@ class Trainingjobsetting extends Component { Botval:`本操作只对"未发布"的分班有效`, starttime: "发布时间:" + moment(moment(new Date())).format("YYYY-MM-DD HH:mm"), starttimes:starttime, - starttimesend:response.data.end_time===undefined||response.data.end_time===null||response.data.end_time===""?undefined:moment(response.data.end_time, dataformat), + starttimesend:response.data.end_time===undefined||response.data.end_time===null||response.data.end_time===""?undefined:response.data.end_time, typs:"start", endtime: "截止时间:" + endtime, Cancelname: "暂不发布", diff --git a/public/react/src/modules/courses/shixunHomework/Workquestionandanswer.js b/public/react/src/modules/courses/shixunHomework/Workquestionandanswer.js index f211b4a1d..34c484b83 100644 --- a/public/react/src/modules/courses/shixunHomework/Workquestionandanswer.js +++ b/public/react/src/modules/courses/shixunHomework/Workquestionandanswer.js @@ -175,7 +175,7 @@ class Workquestionandanswer extends Component { Saves: this.homeworkstartend, course_groups: response.data.course_groups, starttimes: starttime, - starttimesend:response.data.end_time===undefined||response.data.end_time===null||response.data.end_time===""?undefined:moment(response.data.end_time, dataformat), + starttimesend:response.data.end_time===undefined||response.data.end_time===null||response.data.end_time===""?undefined:response.data.end_time, typs: "start", }) } From 8817c87677bc43155a0dce5f735daa0de2bd1f78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Sat, 12 Oct 2019 16:45:05 +0800 Subject: [PATCH 048/252] =?UTF-8?q?=E7=94=A8=E6=88=B7=E5=AF=86=E7=A0=81?= =?UTF-8?q?=E8=A7=84=E5=88=99=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/AppConfig.js | 24 +++++++++---------- .../src/modules/user/account/AccountSecure.js | 24 +++++++++++++------ 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/public/react/src/AppConfig.js b/public/react/src/AppConfig.js index 98571d818..c00c5fb62 100644 --- a/public/react/src/AppConfig.js +++ b/public/react/src/AppConfig.js @@ -21,16 +21,16 @@ let hashTimeout // TODO 开发期多个身份切换 let debugType ="" -// if (isDev) { -// const _search = window.location.search; -// let parsed = {}; -// if (_search) { -// parsed = queryString.parse(_search); -// } -// debugType = window.location.search.indexOf('debug=t') != -1 ? 'teacher' : -// window.location.search.indexOf('debug=s') != -1 ? 'student' : -// window.location.search.indexOf('debug=a') != -1 ? 'admin' : parsed.debug || 'admin' -// } +if (isDev) { + const _search = window.location.search; + let parsed = {}; + if (_search) { + parsed = queryString.parse(_search); + } + debugType = window.location.search.indexOf('debug=t') != -1 ? 'teacher' : + window.location.search.indexOf('debug=s') != -1 ? 'student' : + window.location.search.indexOf('debug=a') != -1 ? 'admin' : parsed.debug || 'admin' +} window._debugType = debugType; export function initAxiosInterceptors(props) { initOnlineOfflineListener() @@ -84,9 +84,9 @@ export function initAxiosInterceptors(props) { } config.url = `${proxy}${url}`; if (config.url.indexOf('?') == -1) { - config.url = `${config.url}?debug=${debugType}`; + config.url = `${config.url}?debug=${'student'}`; } else { - config.url = `${config.url}&debug=${debugType}`; + config.url = `${config.url}&debug=${'student'}`; } } else { // 加api前缀 diff --git a/public/react/src/modules/user/account/AccountSecure.js b/public/react/src/modules/user/account/AccountSecure.js index 797b350d2..2e90824c9 100644 --- a/public/react/src/modules/user/account/AccountSecure.js +++ b/public/react/src/modules/user/account/AccountSecure.js @@ -153,20 +153,28 @@ class AccountSecure extends Component { }) } onPasswordSubmit = () => { + let {basicInfo}=this.props; this.props.form.validateFieldsAndScroll((err, values) => { if (!err) { - if(values.p_old == values.p_new){ - this.props.showNotification("新密码不能与旧密码相同!"); - return; - } + if(basicInfo&&basicInfo.has_password===true){ + if(values.p_old == values.p_new){ + this.props.showNotification("新密码不能与旧密码相同!"); + return; + } + } + if(values.p_again != values.p_new){ this.props.showNotification("两次输入的新密码必须一致!"); return; } let {login}=this.props.current_user; let url=`/users/accounts/${login}/password.json`; + let p_old=undefined; + if(basicInfo&&basicInfo.has_password===true){ + p_old=values.p_old + } axios.put((url),{ - old_password:values.p_old, + old_password:p_old, password:values.p_new }).then((result)=>{ if(result){ @@ -215,6 +223,8 @@ class AccountSecure extends Component { let {basicInfo}=this.props; const { getFieldDecorator } = this.props.form; const { updating,seconds,secondsFlag } = this.state + + console.log(basicInfo&&basicInfo.has_password) return (
    @@ -426,7 +436,7 @@ class AccountSecure extends Component { { updating == PASSWORD && - @@ -439,7 +449,7 @@ class AccountSecure extends Component { })( )} - + :""} Date: Sat, 12 Oct 2019 16:45:59 +0800 Subject: [PATCH 049/252] admins: fix search identifier ineffective at laboratory list --- app/queries/admins/laboratory_query.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/queries/admins/laboratory_query.rb b/app/queries/admins/laboratory_query.rb index 21020216b..8667bb8ed 100644 --- a/app/queries/admins/laboratory_query.rb +++ b/app/queries/admins/laboratory_query.rb @@ -15,7 +15,7 @@ class Admins::LaboratoryQuery < ApplicationQuery keyword = strip_param(:keyword) if keyword.present? like_sql = 'schools.name LIKE :keyword OR laboratories.identifier LIKE :keyword' - laboratories = laboratories.joins(:school).where(like_sql, keyword: "%#{keyword}%") + laboratories = laboratories.left_joins(:school).where(like_sql, keyword: "%#{keyword}%") end custom_sort laboratories, params[:sort_by], params[:sort_direction] From 558a7051ab12bfeef33f7ec41e53b780e06302b7 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Sat, 12 Oct 2019 16:51:30 +0800 Subject: [PATCH 050/252] =?UTF-8?q?=E8=AF=95=E5=8D=B7=E8=AF=84=E9=98=85?= =?UTF-8?q?=E9=A1=B5=E7=9A=84=E9=A1=B5=E9=9D=A2=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/exercises_controller.rb | 6 +++--- app/helpers/exercises_helper.rb | 16 ++++++++-------- .../exercises/_user_exercise_info.json.jbuilder | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/controllers/exercises_controller.rb b/app/controllers/exercises_controller.rb index 74059b314..9979ae48f 100644 --- a/app/controllers/exercises_controller.rb +++ b/app/controllers/exercises_controller.rb @@ -1152,7 +1152,7 @@ class ExercisesController < ApplicationController # 1 老师权限,0 学生权限 @is_teacher_or = (@user_course_identity < Course::STUDENT) ? 1 : 0 @student_status = 2 - @exercise_questions = @exercise.exercise_questions.includes(:exercise_shixun_challenges,:exercise_standard_answers,:exercise_answers,:exercise_shixun_answers).order("question_number ASC") + @exercise_questions = @exercise.exercise_questions.includes(:exercise_shixun_challenges,:exercise_standard_answers,:exercise_answers,:exercise_shixun_answers,:exercise_answer_comments).order("question_number ASC") @question_status = [] get_exercise_status = @exercise.get_exercise_status(current_user) #当前用户的试卷状态 @ex_answer_status = @exercise.get_exercise_status(@ex_user&.user) #当前试卷用户的试卷状态 @@ -1709,9 +1709,9 @@ class ExercisesController < ApplicationController ques_number = q.question_number end if q.question_type != Exercise::PRACTICAL - ques_vote = q.exercise_answers.search_exercise_answer("user_id",user_id) + ques_vote = q.exercise_answers.select{|answer| answer.user_id == user_id} else - ques_vote = q.exercise_shixun_answers.search_shixun_answers("user_id",user_id) + ques_vote = q.exercise_shixun_answers.select{|answer| answer.user_id == user_id} end ques_status = 0 if ques_vote.present? diff --git a/app/helpers/exercises_helper.rb b/app/helpers/exercises_helper.rb index ef9261990..e13f754be 100644 --- a/app/helpers/exercises_helper.rb +++ b/app/helpers/exercises_helper.rb @@ -10,9 +10,9 @@ module ExercisesHelper exercise_obj_status.each do |q| q_type = q.question_type if q_type == Exercise::PRACTICAL - answers_content = q.exercise_shixun_answers.search_shixun_answers("user_id",user_id) + answers_content = q.exercise_shixun_answers.select{|answer| answer.user_id == user_id} else - answers_content = q.exercise_answers.search_answer_users("user_id",user_id) + answers_content = q.exercise_answers.select{|answer| answer.user_id == user_id} end if q_type <= Exercise::JUDGMENT @@ -40,7 +40,7 @@ module ExercisesHelper ques_score = 0.0 end else - ques_score = answers_content.score_reviewed.select(:score).pluck(:score).sum + ques_score = answers_content.select{|answer| answer.score >= 0.0}.pluck(:score).sum end if ques_score >= q.question_score #满分作答为正确 @@ -64,7 +64,7 @@ module ExercisesHelper exercise_sub_status = exercise_questions.find_by_custom("question_type",Exercise::SUBJECTIVE) #主观题 @ex_sub_array = [] #主观题的已答/未答 exercise_sub_status.each do |s| - sub_answer = s.exercise_answers.search_answer_users("user_id",user_id) #主观题只有一个回答 + sub_answer = s.exercise_answers.select{|answer| answer.user_id == user_id} #主观题只有一个回答 if sub_answer.present? && sub_answer.first.score >= 0.0 if s.question_score <= sub_answer.first.score stand_status = 1 @@ -772,12 +772,12 @@ module ExercisesHelper question_comment = [] # user_score_pre = nil if ques_type == 5 - exercise_answers = q.exercise_shixun_answers.search_shixun_answers("user_id",ex_answerer_id) + exercise_answers = q.exercise_shixun_answers.select{|answer| answer.user_id == ex_answerer_id} else - exercise_answers = q.exercise_answers.search_exercise_answer("user_id",ex_answerer_id) #试卷用户的回答 + exercise_answers = q.exercise_answers.select{|answer| answer.user_id == ex_answerer_id} #试卷用户的回答 end if student_status == 2 #当前为老师,或为学生且已提交 - user_score_pre = exercise_answers.score_reviewed + user_score_pre = exercise_answers.select{|answer| answer.score >= 0.0} if ques_type == 4 #主观题时,且没有大于0的分数时,为空 user_score = user_score_pre.present? ? user_score_pre.pluck(:score).sum : nil elsif ques_type == 5 || ques_type == 3 @@ -829,7 +829,7 @@ module ExercisesHelper if ex_type == 4 #填空题/主观题/实训题有评论的 q_answer_id = exercise_answers.present? ? exercise_answers.first.id : nil - question_comment = q.exercise_answer_comments.search_answer_comments("exercise_answer_id",q_answer_id) + question_comment = q.exercise_answer_comments.select{|comment| comment.exercise_answer_id == q_answer_id} end { "user_score": (user_score.present? ? user_score.round(1).to_s : nil), diff --git a/app/views/exercises/_user_exercise_info.json.jbuilder b/app/views/exercises/_user_exercise_info.json.jbuilder index bdac3a985..c351a9b26 100644 --- a/app/views/exercises/_user_exercise_info.json.jbuilder +++ b/app/views/exercises/_user_exercise_info.json.jbuilder @@ -65,7 +65,7 @@ json.exercise_questions do shixun_type: user_ques_answers[:shixun_type], ques_position: nil, edit_type:nil - if user_ques_comments.count > 0 + if user_ques_comments.size > 0 json.question_comments do json.partial! "exercises/exercise_comments", question_comment:user_ques_answers[:question_comment].first end From 4a3837cd9014addc018cafb35c9d8e44046fece2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Sat, 12 Oct 2019 16:52:56 +0800 Subject: [PATCH 051/252] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../graduation/tasks/GraduationTaskDetail.js | 725 +++++++++--------- 1 file changed, 358 insertions(+), 367 deletions(-) diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTaskDetail.js b/public/react/src/modules/courses/graduation/tasks/GraduationTaskDetail.js index fbbfafabc..66e4ccb8d 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTaskDetail.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTaskDetail.js @@ -7,7 +7,6 @@ import Loading from '../../../../Loading'; import {BrowserRouter as Router,Route,Switch} from 'react-router-dom'; import axios from 'axios'; import HomeworkModal from "../../coursesPublic/HomeworkModal"; -import OneSelfOrderModal from "../../coursesPublic/OneSelfOrderModal"; import AccessoryModal from "../../coursesPublic/AccessoryModal"; import Associationmodel from '../../coursesPublic/Associationmodel'; import CoursesListType from '../../coursesPublic/CoursesListType'; @@ -21,90 +20,89 @@ import Modals from '../../../modals/Modals'; //毕设描述 const GraduationTasksquestions= Loadable({ - loader: () => import('./GraduationTaskssettingquestions'), - loading: Loading, + loader: () => import('./GraduationTaskssettingquestions'), + loading: Loading, }) //毕设任务设置 const GraduationTaskssetting=Loadable({ - loader: () => import('./GraduationTaskssetting'), - loading: Loading, + loader: () => import('./GraduationTaskssetting'), + loading: Loading, }) //毕设任务列表 const GraduationTaskslist=Loadable({ - loader: () => import('./GraduationTaskssettinglist'), - loading: Loading, + loader: () => import('./GraduationTaskssettinglist'), + loading: Loading, }) class GraduationTaskDetail extends Component{ - constructor(props){ - super(props); - this.state={ - modalname:undefined, - visible:false, - OneSelftype:false, + constructor(props){ + super(props); + this.state={ + modalname:undefined, + visible:false, Topval:undefined, starttime:undefined, starttimes:undefined, typs:undefined, - endtime:undefined, - Cancelname:undefined, - Savesname:undefined, - Cancel:undefined, - Saves:undefined, - Topvalright:undefined, - Botvalleft:undefined, - course_groupslist:undefined, - course_groups:undefined, - questionslist:undefined, - tab:"list", - visibles:undefined, - Modalstype:undefined, - Modalstopval:undefined, - ModalCancel:undefined, - ModalSave:undefined, - acrossVisible:undefined - } - } - componentDidMount(){ - this.getdatas() - } - getdatas=()=>{ - const task_Id = this.props.match.params.task_Id; - let url="/graduation_tasks/"+task_Id+".json"; - - axios.get(url).then((result)=>{ - if(result.status===200){ - this.setState({ - questionslist:result.data - }) - - } - }).catch((error)=>{ - console.log(error) - }) - } - - - // 交叉评阅设置弹框 - openAcross=()=>{ - this.setState({ - acrossVisible:true - }) - } - closeAcross=()=>{ - this.setState({ - acrossVisible:false - }) + endtime:undefined, + Cancelname:undefined, + Savesname:undefined, + Cancel:undefined, + Saves:undefined, + Topvalright:undefined, + Botvalleft:undefined, + course_groupslist:undefined, + course_groups:undefined, + questionslist:undefined, + tab:"list", + visibles:undefined, + Modalstype:undefined, + Modalstopval:undefined, + ModalCancel:undefined, + ModalSave:undefined, + acrossVisible:undefined + } + } + componentDidMount(){ + this.getdatas() + } + getdatas=()=>{ + const task_Id = this.props.match.params.task_Id; + let url="/graduation_tasks/"+task_Id+".json"; + + axios.get(url).then((result)=>{ + if(result.status===200){ + this.setState({ + questionslist:result.data + }) + + } + }).catch((error)=>{ + console.log(error) + }) + } + + + // 交叉评阅设置弹框 + openAcross=()=>{ + this.setState({ + acrossVisible:true + }) + } + closeAcross=()=>{ + this.setState({ + acrossVisible:false + }) this.getdatas() - } + } - //返回 - goback=()=>{ - // let courseId=this.props.match.params.coursesId; - // let category_id=this.props.match.params.category_id; - // window.location.href="/courses/"+courseId+"/graduation_tasks/"+category_id; + //返回 + goback=()=>{ + // let courseId=this.props.match.params.coursesId; + // let category_id=this.props.match.params.category_id; + // window.location.href="/courses/"+courseId+"/graduation_tasks/"+category_id; // let courseId = this.props.match.params.coursesId; // if(courseId===undefined){ // this.props.history.push("/courses"); @@ -114,76 +112,71 @@ class GraduationTaskDetail extends Component{ // this.props.history.goBack() this.props.history.replace(`/courses/${this.state.questionslist.course_id}/graduation_tasks/${this.state.questionslist.graduation_id}`); - } - //立即发布 - publish=()=>{ - let {questionslist}=this.state; - let starttime= this.props.getNowFormatDates(1,1); - let endtime=this.props.getNowFormatDates(2,1); - // this.homeworkstart() - this.setState({ - modalname:"立即发布", - visible:true, - OneSelftype:true, + } + //立即发布 + publish=()=>{ + let starttime= this.props.getNowFormatDates(1,1); + let endtime=this.props.getNowFormatDates(2,1); + // this.homeworkstart() + this.setState({ + modalname:"立即发布", + visible:true, Topval:"学生将立即收到毕设任务", - // Botvalleft:"点击修改", + // Botvalleft:"点击修改", // Botval:`本操作只对"未发布"的分班有效`, starttime:moment(moment(new Date())).format("YYYY-MM-DD HH:mm") , - starttimes:questionslist.end_time, - staytime:this.props.getNowFormatDates(1), + starttimes:this.props.getNowFormatDates(1), typs:"start", - endtime:endtime, - Cancelname:"暂不发布", - Savesname:"立即发布", - Cancel:this.cancelmodel, - Saves:this.homepublish, - }) - } - // 确定立即发布 - homepublish=(ids,endtime)=>{ - this.cancelmodel(); - let task_Id=this.props.match.params.task_Id; - const cid = this.props.match.params.coursesId; - // let url = `/courses/${cid}/graduation_tasks/publish_task.json`; - - let url="/courses/"+cid+"/graduation_tasks/publish_task.json" - axios.post(url,{ - task_ids:[task_Id], - group_ids: this.state.course_groupslist, + endtime:endtime, + Cancelname:"暂不发布", + Savesname:"立即发布", + Cancel:this.cancelmodel, + Saves:this.homepublish, + }) + } + // 确定立即发布 + homepublish=(ids,endtime)=>{ + this.cancelmodel(); + let task_Id=this.props.match.params.task_Id; + const cid = this.props.match.params.coursesId; + // let url = `/courses/${cid}/graduation_tasks/publish_task.json`; + + let url="/courses/"+cid+"/graduation_tasks/publish_task.json" + axios.post(url,{ + task_ids:[task_Id], + group_ids: this.state.course_groupslist, end_time:endtime, - }).then((response)=>{ - if (response.data.status == 0) { + }).then((response)=>{ + if (response.data.status == 0) { this.getdatas() - this.props.showNotification(response.data.message); - - this.setState({ - // Modalstopval:response.data.message, - // ModalSave:this.cancelmodel, - // Loadtype:true, - course_groupslist:[], - checkAllValue:false - }) - } - }).catch((error)=>{ - - }) - } - - // 刷新 - resetList=()=>{ - this.getdatas(); - this.child && this.child.searchValue(); - } - - // 立即截止 - end=()=>{ + this.props.showNotification(response.data.message); + + this.setState({ + // Modalstopval:response.data.message, + // ModalSave:this.cancelmodel, + // Loadtype:true, + course_groupslist:[], + checkAllValue:false + }) + } + }).catch((error)=>{ + + }) + } + + // 刷新 + resetList=()=>{ + this.getdatas(); + this.child && this.child.searchValue(); + } + + // 立即截止 + end=()=>{ // this.homeworkstart() this.setState({ modalname:"立即截止", visible:true, - OneSelftype:true, Topval:"学生将不能再提交作品", - starttime:undefined, // Botvalleft:"暂不截止", // Botval:`本操作只对"提交中"的分班有效`, Cancelname:"暂不截止", @@ -192,75 +185,74 @@ class GraduationTaskDetail extends Component{ Saves:this.coursetaskend, typs:"end", }) - } - coursetaskend=()=>{ - const coursesId = this.props.match.params.coursesId; - const task_Id = this.props.match.params.task_Id; - - let url = `/courses/${coursesId}/graduation_tasks/end_task.json`; - axios.post(url,{ - task_ids:[task_Id], - group_ids: this.state.course_groupslist, - }).then((response)=>{ - if (response.data.status == 0) { - this.props.showNotification(response.data.message); - this.cancelmodel(); - this.getdatas(); - this.child && this.child.reInit(); - } - - }).catch((error)=>{ - - }) - } - // 取消 - cancelmodel=()=>{ - this.setState({ - Modalstype:false, - Loadtype:false, - visible:false, - OneSelftype:false, - Modulationtype:false, - Allocationtype:false, - Modalstopval:"", - ModalCancel:"", - ModalSave:"", - }) - } - - getcourse_groupslist=(id)=>{ - this.setState({ - course_groupslist:id - }) - } - - setTab = (tab) =>{ - this.setState({ - tab - }) - } - - // 关联项目 - AssociationItems=()=>{ + } + coursetaskend=()=>{ + const coursesId = this.props.match.params.coursesId; + const task_Id = this.props.match.params.task_Id; + + let url = `/courses/${coursesId}/graduation_tasks/end_task.json`; + axios.post(url,{ + task_ids:[task_Id], + group_ids: this.state.course_groupslist, + }).then((response)=>{ + if (response.data.status == 0) { + this.props.showNotification(response.data.message); + this.cancelmodel(); + this.getdatas(); + this.child && this.child.reInit(); + } + + }).catch((error)=>{ + + }) + } + // 取消 + cancelmodel=()=>{ + this.setState({ + Modalstype:false, + Loadtype:false, + visible:false, + Modulationtype:false, + Allocationtype:false, + Modalstopval:"", + ModalCancel:"", + ModalSave:"", + }) + } + + getcourse_groupslist=(id)=>{ + this.setState({ + course_groupslist:id + }) + } + + setTab = (tab) =>{ + this.setState({ + tab + }) + } + + // 关联项目 + AssociationItems=()=>{ this.setState({ visibles:true }) - } - Cancel=()=>{ + } + Cancel=()=>{ this.setState({ visibles:false }) - } - // 取消关联 - cannelAssociation=()=>{ + } + // 取消关联 + cannelAssociation=()=>{ this.setState({ Modalstype:true, Modalstopval:"确定要取消该项目关联?", ModalCancel:this.cannerassocition, ModalSave:this.savetassociton }) - } - savetassociton=()=>{ + } + savetassociton=()=>{ this.cannerassocition(); let {questionslist}=this.state; let url = "/graduation_tasks/"+questionslist.task_id+"/graduation_works/cancel_relate_project.json"; @@ -274,7 +266,7 @@ class GraduationTaskDetail extends Component{ }) } - cannerassocition=()=>{ + cannerassocition=()=>{ this.setState({ Modalstype:false, Modalstopval:"", @@ -283,10 +275,10 @@ class GraduationTaskDetail extends Component{ loadtype:false, visibles:false }) - } - // 补交附件 - handaccessory=()=>{ - // let {taskslistdata}=this.state; + } + // 补交附件 + handaccessory=()=>{ + // let {taskslistdata}=this.state; // let courseId=this.props.match.params.coursesId; // // let url="/courses/"+courseId+"/graduation_tasks/"+taskslistdata.work_id+"/appraise" @@ -300,130 +292,129 @@ class GraduationTaskDetail extends Component{ this.setState({ avisible:false }) - } - - - bindRef = ref => { this.child = ref } ; - render(){ - - let courseId=this.props.match.params.coursesId; - let category_id=this.props.match.params.category_id; - let task_Id=this.props.match.params.task_Id; - let { - questionslist , - tab , - visibles , - Modalstype, - Modalstopval, - ModalCancel, - ModalSave, - acrossVisible - } = this.state - - const commom = { - setTab:this.setTab, - getdatas:this.getdatas - } - return( -
    - { - questionslist && -
    - this.getcourse_groupslist(id)} - /> - {/*关联项目*/} - {visibles===true? - this.Cancel()} - taskid={ questionslist && questionslist.task_id } - funlist={this.resetList} - /> - :""} - - {this.state.avisible===true?:""} - {/*提示*/} - - - { - acrossVisible && - - } - -

    - {questionslist.course_name} - > - {questionslist.graduation_name} - > - 任务详情 -

    -
    -

    - {questionslist.task_name} -

    - - 返回 -
    -
    -
    - - 任务列表 - 毕设描述 - 设置 - - {/*导出成绩*/} - {/*{this.props.isAdmin()?导出成绩:""}*/} - {/*{this.props.isAdmin()?导出作品附件:""}*/} - - - {this.props.isAdmin()?
  • - 导出 - -
  • :""} - {questionslist.work_status===undefined||questionslist.work_status===null||questionslist.work_status.length===0?"":questionslist.work_status.map((item,key)=>{ - return( - + + {this.props.isAdmin()?
  • + 导出 + +
  • :""} + {questionslist.work_status===undefined||questionslist.work_status===null||questionslist.work_status.length===0?"":questionslist.work_status.map((item,key)=>{ + return( + {item==="提交作品"?提交作品:""} - {item==="补交作品"?补交作品:""} - {item==="修改作品"?修改作品:""} - {item==="查看作品"?查看作品 :""} - {item==="创建项目"?创建项目:""} - {item==="关联项目"?关联项目:""} - {item==="取消关联"?取消关联:""} - {item==="补交附件"?补交附件:""} + {item==="补交作品"?补交作品:""} + {item==="修改作品"?修改作品:""} + {item==="查看作品"?查看作品 :""} + {item==="创建项目"?创建项目:""} + {item==="关联项目"?关联项目:""} + {item==="取消关联"?取消关联:""} + {item==="补交附件"?补交附件:""} - ) - })} - - {/*项目在线质量检测*/} - { this.props.isAdmin() ? questionslist.status===1 ? { this.end()} }>立即截止 : "" : "" } - { this.props.isAdmin() ? questionslist.status===0 ? { this.publish()} }>立即发布 : "" : "" } - { this.props.isAdmin() && questionslist.cross_comment ? 交叉评阅设置 : "" } - { this.props.isAdmin() ? 编辑任务 : "" } -
    -
    - - - () - } - > - - () - } - > - - () - }> - - -
    - } - -
    - ) - } + ) + })} + + {/*项目在线质量检测*/} + { this.props.isAdmin() ? questionslist.status===1 ? { this.end()} }>立即截止 : "" : "" } + { this.props.isAdmin() ? questionslist.status===0 ? { this.publish()} }>立即发布 : "" : "" } + { this.props.isAdmin() && questionslist.cross_comment ? 交叉评阅设置 : "" } + { this.props.isAdmin() ? 编辑任务 : "" } +
    +
    + + + () + } + > + + () + } + > + + () + }> + + +
    + } + +
    + ) + } } // CNotificationHOC() ( SnackbarHOC() ( TPMIndexHOC)) export default (GraduationTaskDetail) ; \ No newline at end of file From 11a16c74034c7f9ec9b7bdadf54bbd9ddb840c1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Sat, 12 Oct 2019 16:54:35 +0800 Subject: [PATCH 052/252] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/AppConfig.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/react/src/AppConfig.js b/public/react/src/AppConfig.js index c00c5fb62..e1d5da561 100644 --- a/public/react/src/AppConfig.js +++ b/public/react/src/AppConfig.js @@ -84,9 +84,9 @@ export function initAxiosInterceptors(props) { } config.url = `${proxy}${url}`; if (config.url.indexOf('?') == -1) { - config.url = `${config.url}?debug=${'student'}`; + config.url = `${config.url}?debug=${debugType}`; } else { - config.url = `${config.url}&debug=${'student'}`; + config.url = `${config.url}&debug=${debugType}`; } } else { // 加api前缀 From d56850e32ce5618320fec2f90d47ca13584f5dc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Sat, 12 Oct 2019 16:59:21 +0800 Subject: [PATCH 053/252] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shixunHomework/Listofworksstudentone.js | 1046 ++++++++--------- 1 file changed, 523 insertions(+), 523 deletions(-) diff --git a/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js b/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js index 857b5c244..46e90befb 100644 --- a/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js +++ b/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js @@ -31,7 +31,7 @@ import TraineetraininginformationModal from "./TraineetraininginformationModal"; import DownloadMessageysl from '../../modals/DownloadMessageysl'; import Startshixuntask from "../coursesPublic/Startshixuntask"; import ModulationModal from "../coursesPublic/ModulationModal"; -import OneSelfOrderModal from "../coursesPublic/OneSelfOrderModal"; +import HomeworkModal from "../coursesPublic/HomeworkModal"; import ShixunWorkModal from "./Shixunworkdetails/ShixunWorkModal"; import NoneData from '../../../modules/courses/coursesPublic/NoneData'; @@ -210,13 +210,13 @@ class Listofworksstudentone extends Component { title={record.stduynumber} className="maxnamewidth145" style={{ - color:'#9A9A9A', + color:'#9A9A9A', textAlign: "center", width:'145px', - }}>{ + }}>{ record.stduynumber } - + } @@ -327,11 +327,11 @@ class Listofworksstudentone extends Component { // className:'font-14', // render: (text, record) => ( // - // {record.updatetime === undefined ? "--" : record.updatetime === "" ? "--" : record.updatetime} - // + // // ), // }, { @@ -451,8 +451,8 @@ class Listofworksstudentone extends Component { record.submitstate === "未提交" ?-- : this.Viewstudenttraininginformation(record)}>{record.operating} + className="color-blue" + onClick={() => this.Viewstudenttraininginformation(record)}>{record.operating} } @@ -953,15 +953,15 @@ class Listofworksstudentone extends Component { } - // {record.cost_time === null ? "--":record.cost_time === undefined ?"--":record.cost_time } - // + // {record.cost_time === null ? "--":record.cost_time === undefined ?"--":record.cost_time } + // ) }, @@ -1268,14 +1268,14 @@ class Listofworksstudentone extends Component { 学员在EduCoder做实训花费的时间
    }> - {record.cost_time === null ? "--":record.cost_time === undefined ?"--":record.cost_time} - + >{record.cost_time === null ? "--":record.cost_time === undefined ?"--":record.cost_time} + } @@ -1535,7 +1535,7 @@ class Listofworksstudentone extends Component { // console.log("获取作品列表"); // console.log("935"); // debugger - let searchtype=this.props.history.location.search; + let searchtype=this.props.history.location.search; let urll = `/homework_commons/${homeworkid}/works_list.json`; var datasysl = { search: this.state.searchtext, @@ -1589,12 +1589,12 @@ class Listofworksstudentone extends Component { if(result.data.update_score===true){ if(bool===true){ if(searchtype==="?tab=0"){ - try { - this.props.yslslowCheckresults(); - }catch (e) { + try { + this.props.yslslowCheckresults(); + }catch (e) { - } - this.setComputeTimet(); + } + this.setComputeTimet(); } } } @@ -2445,7 +2445,7 @@ class Listofworksstudentone extends Component { if(item.title==="效率分"){ continue }else { - columns2js.push(item); + columns2js.push(item); } } } @@ -2479,7 +2479,7 @@ class Listofworksstudentone extends Component { if(item.title==="分班"){ continue }else{ - columns2js.push(item); + columns2js.push(item); } } } @@ -2794,11 +2794,11 @@ class Listofworksstudentone extends Component { this.setState({ modalname: "立即发布", modaltype: response.data.course_groups === null || response.data.course_groups.length === 0 ? 2 : 1, - OneSelftype: true, + svisible: true, Topval:"学生将立即收到作业", // Botvalleft:"暂不发布", - Botval:``, - starttime:moment(moment(new Date())).format("YYYY-MM-DD HH:mm"), + Botval:`本操作只对"未发布"的分班有效`, + starttime: "发布时间:" + moment(moment(new Date())).format("YYYY-MM-DD HH:mm"), endtime: "截止时间:" + endtime, starttimes:starttime, typs:"start", @@ -2828,7 +2828,7 @@ class Listofworksstudentone extends Component { this.setState({ modalname: "立即截止", modaltype: response.data.course_groups === null || response.data.course_groups.length === 0 ? 2 : 1, - OneSelftype: true, + svisible: true, Topval:"学生将不能再提交作业", // Botvalleft:"暂不截止", Botval:`本操作只对"提交中"的分班有效`, @@ -2931,7 +2931,7 @@ class Listofworksstudentone extends Component { this.setState({ modalname: undefined, modaltype: undefined, - OneSelftype: false, + svisible: false, Topval: undefined, Topvalright: undefined, Botvalleft: undefined, @@ -2985,31 +2985,31 @@ class Listofworksstudentone extends Component { let url = "/homework_commons/"+homeworkid+"/update_score.json"; axios.get(url).then((response) => { - if(response){ - if(response.data.status===0){ - // if(response.data.message!==undefined){ - // return; - // } + if(response){ + if(response.data.status===0){ + // if(response.data.message!==undefined){ + // return; + // } setTimeout(()=>{ this.setState({ loadingstate: true }) this.Getalistofworks(homeworkid,false); - try { - this.props.showNotification(`${response.data.message}`); - }catch (e) { + try { + this.props.showNotification(`${response.data.message}`); + }catch (e) { - } - try{ - this.props.yslslowCheckresultsNo(); - }catch (e) { + } + try{ + this.props.yslslowCheckresultsNo(); + }catch (e) { - } + } }, 2500); } - // this.props.history.replace( matchurl ); - } + // this.props.history.replace( matchurl ); + } }).catch((error) => { console.log(error) }); @@ -3038,8 +3038,8 @@ class Listofworksstudentone extends Component { // } daochushixunbaogao=()=>{ - let url =`/zip/shixun_report?homework_common_id=${this.props.match.params.homeworkid}&work_status=${this.state.course_groupyslstwo===undefined ||this.state.course_groupyslstwo===null? "": this.state.course_groupyslstwo}&course_group=${this.state.checkedValuesineinfo===undefined||this.state.checkedValuesineinfo===null? "":this.state.checkedValuesineinfo}&search=${this.state.searchtext===undefined||this.state.searchtext===null?"":this.state.searchtext}` - this.confirmysl(url); + let url =`/zip/shixun_report?homework_common_id=${this.props.match.params.homeworkid}&work_status=${this.state.course_groupyslstwo===undefined ||this.state.course_groupyslstwo===null? "": this.state.course_groupyslstwo}&course_group=${this.state.checkedValuesineinfo===undefined||this.state.checkedValuesineinfo===null? "":this.state.checkedValuesineinfo}&search=${this.state.searchtext===undefined||this.state.searchtext===null?"":this.state.searchtext}` + this.confirmysl(url); } daochuzuoye =() =>{ @@ -3092,105 +3092,105 @@ class Listofworksstudentone extends Component { let {columns,course_groupysls,datajs,isAdmin,homework_status, course_groupyslstwo, unlimited, unlimitedtwo, course_group_info, orders, task_status, checkedValuesine, searchtext, teacherlist, visible,visibles, game_list,columnsstu,columnsstu2, limit,experience, boolgalist,viewtrainingdata, teacherdata, page, data, jobsettingsdata, styletable, datas, order, loadingstate,computeTimetype} = this.state; const antIcon = ; - let course_is_end = this.props.current_user&&this.props.current_user.course_is_end; - // console.log("Listofworksstudentone.js"); - // console.log(orders); + let course_is_end = this.props.current_user&&this.props.current_user.course_is_end; + // console.log("Listofworksstudentone.js"); + // console.log(orders); return ( this.props.isAdmin() === true ? -
    - {visible === true ? this.saveModulationModal(value, num)} - /> : ""} - - {this.state.showmodel === true ? this.hideshowmodel()} - updatas={() => this.isupdatas()} - /> : ""} - - - {visibles === true ? -
    - - this.cancelModulationModels()} - /> - -
    - : "" - } - - {/*立即发布*/} - this.getcourse_groupslist(id)} - starttimes={this.state.starttimes} - typs={this.state.typs} - /> - { - homework_status&&homework_status.length===0? -
    - -
    - : - homework_status&&homework_status.length>0 && homework_status[0]==="未发布"? -
    - -
    - : -
    - - -
    - - - + this.cancelModulationModels()} + /> + +
    + : "" + } + + {/*立即发布*/} + this.getcourse_groupslist(id)} + starttimes={this.state.starttimes} + typs={this.state.typs} + /> + { + homework_status&&homework_status.length===0? +
    + +
    + : + homework_status&&homework_status.length>0 && homework_status[0]==="未发布"? +
    + +
    + : +
    + + +
    + + + - {computeTimetype===false?
  • - - + + {computeTimetype===false?
  • + + 正在执行成绩计算,完成后将为您自动刷新结果。温馨提示:执行时间因作品数量而异 -
  • :""} - - {/*作品状态GraduationTaskssettinglist*/} -
      -
    • - {/*计算成绩时间:{teacherdata&&teacherdata.calculation_time==null?"--": moment(teacherdata&&teacherdata.calculation_time).format('YYYY-MM-DD HH:mm')}*/} - - - -
    • - -
    • -
      - {/*{course_is_end===true?"":*/} - {/*{teacherdata&&teacherdata.update_score===true&&computeTimetype===true?*/} - {/* (this.props.isNotMember()===false?
      */} - {/* 查看最新成绩*/} - {/*
      :""):*/} - {/* teacherdata&&teacherdata.homework_status!==undefined&&teacherdata.homework_status[0]=== "未发布"? "":*/} - {/* (this.props.isNotMember()===false?
      */} - {/* 查看最新成绩*/} - {/*
      :"")*/} - {/*}*/} - {/*
      }*/} - +
    • :""} + + {/*作品状态GraduationTaskssettinglist*/} +
        +
      • + {/*计算成绩时间:{teacherdata&&teacherdata.calculation_time==null?"--": moment(teacherdata&&teacherdata.calculation_time).format('YYYY-MM-DD HH:mm')}*/} + + + +
      • + +
      • +
        + {/*{course_is_end===true?"":*/} + {/*{teacherdata&&teacherdata.update_score===true&&computeTimetype===true?*/} + {/* (this.props.isNotMember()===false?
        */} + {/* 查看最新成绩*/} + {/*
        :""):*/} + {/* teacherdata&&teacherdata.homework_status!==undefined&&teacherdata.homework_status[0]=== "未发布"? "":*/} + {/* (this.props.isNotMember()===false?
        */} + {/* 查看最新成绩*/} + {/*
        :"")*/} + {/*}*/} + {/*
        }*/} + -
        - 作品状态: - this.notlimiteds()}>不限 - this.funtaskstatust(e, task_status && task_status)} - style={{paddingTop: '4px'}}> - - {task_status === undefined ? "" : task_status.map((item, key) => { - return ( - +
    + 作品状态: + this.notlimiteds()}>不限 + this.funtaskstatust(e, task_status && task_status)} + style={{paddingTop: '4px'}}> + + {task_status === undefined ? "" : task_status.map((item, key) => { + return ( + {item.name} @@ -3297,97 +3297,97 @@ class Listofworksstudentone extends Component { - ) - })} - - {/*请输入姓名或学号搜索*/} - - - - - - {/*分班情况*/} - -
  • - {JSON.stringify(course_group_info) === "[]" ? "" : course_group_info === undefined ? "" : course_group_info.length < 2 ? "" : -
    - 分班情况: - this.notlimitedst()}>不限 - this.funtaskstatustwot(e, course_group_info && course_group_info)} - style={{paddingTop: '4px',width:'1017px'}}> - {course_group_info === undefined ? "" : - course_group_info.map((item, key) => { - return ( - + ) + })} + + {/*请输入姓名或学号搜索*/} + + +
  • + + + {/*分班情况*/} + +
  • + {JSON.stringify(course_group_info) === "[]" ? "" : course_group_info === undefined ? "" : course_group_info.length < 2 ? "" : +
    + 分班情况: + this.notlimitedst()}>不限 + this.funtaskstatustwot(e, course_group_info && course_group_info)} + style={{paddingTop: '4px',width:'1017px'}}> + {course_group_info === undefined ? "" : + course_group_info.map((item, key) => { + return ( + {item.group_group_name} ({item.count}) - ) - }) - } - -
    } -
  • + ) + }) + } + +
    } + - + -
    + + { + JSON.stringify(datajs) === "[]" ? + +
    +
    +
    + +

    暂时还没有相关数据哦!

    +
    +
    + +
    + : + +
    + -
    - {datajs === undefined ? "" : } - - - } - - - - { - teacherdata && teacherdata.work_count && teacherdata.work_count > limit ? -
    - -
    - : "" - } - - } - - : +
    + {datajs === undefined ? "" :
    } + + + } -
    + +
    { - teacherdata === undefined || teacherdata.student_works === undefined || teacherdata.student_works === null || JSON.stringify(teacherdata.student_works) === "[]" ? - // 学生不能查看别人的 -
    - - {visibles === true ? -
    - - + {visibles === true ? +
    + + - this.cancelModulationModels()} - /> -
    - : "" - } + } + + this.cancelModulationModels()} + /> +
    + : "" + } - { - homework_status&&homework_status.length&&homework_status.length===0? -
    - -
    - : - homework_status&&homework_status.length>0 && homework_status&&homework_status[0]==="未发布"? -
    - -
    - : + { + homework_status&&homework_status.length&&homework_status.length===0? +
    + +
    + : + homework_status&&homework_status.length>0 && homework_status&&homework_status[0]==="未发布"? +
    + +
    + : -
    -
    +
    +
    - - {computeTimetype===false?
  • - - + + {computeTimetype===false?
  • + + 正在执行成绩计算,完成后将为您自动刷新结果。温馨提示:执行时间因作品数量而异 -
  • :""} + :""} - {JSON.stringify(data) !== "[]" ? -
    -
    + {JSON.stringify(data) !== "[]" ? +
    +
    -
    +
    -
    - - {/*计算成绩时间:{teacherdata&&teacherdata.calculation_time==null?"--": moment(teacherdata&&teacherdata.calculation_time).format('YYYY-MM-DD HH:mm')}*/} - {/* { course_is_end===true?"":teacherdata&&teacherdata.task_operation[0]==="开启挑战"?"":*/} - {/* {computeTimetype===true?*/} - {/* (this.props.isNotMember()===false?*/} - {/* (*/} - {/* teacherdata&&teacherdata.update_score===true?*/} - {/*
    */} - {/* 查看最新成绩*/} - {/*
    */} - {/* :""*/} - {/* )*/} - {/* :"")*/} - {/* :*/} - {/* (teacherdata&&teacherdata.homework_status!==undefined&&teacherdata.homework_status[0]=== "未发布"? "":*/} - {/* this.props.isNotMember()===false?*/} - {/*
    */} - {/* 查看最新成绩*/} - {/*
    */} - {/* :"")*/} - {/* }*/} - {/*
    }*/} - -
    +
    + + {/*计算成绩时间:{teacherdata&&teacherdata.calculation_time==null?"--": moment(teacherdata&&teacherdata.calculation_time).format('YYYY-MM-DD HH:mm')}*/} + {/* { course_is_end===true?"":teacherdata&&teacherdata.task_operation[0]==="开启挑战"?"":*/} + {/* {computeTimetype===true?*/} + {/* (this.props.isNotMember()===false?*/} + {/* (*/} + {/* teacherdata&&teacherdata.update_score===true?*/} + {/*
    */} + {/* 查看最新成绩*/} + {/*
    */} + {/* :""*/} + {/* )*/} + {/* :"")*/} + {/* :*/} + {/* (teacherdata&&teacherdata.homework_status!==undefined&&teacherdata.homework_status[0]=== "未发布"? "":*/} + {/* this.props.isNotMember()===false?*/} + {/*
    */} + {/* 查看最新成绩*/} + {/*
    */} + {/* :"")*/} + {/* }*/} + {/*
    }*/}
    -
    - -
    - {data === undefined ? "" :
    } - +
    + {data === undefined ? "" :
    } + - : -
    -
    -
    - -

    暂时还没有相关数据哦!

    -
    + : +
    +
    +
    + +

    暂时还没有相关数据哦!

    -
    - } -
    +
    + }
    - } + - : - // 学生能查看别人的 -
    - {/*双层*/} - - - {visibles === true ? - this.cancelModulationModels()} - /> : "" - } + } +
    + : + // 学生能查看别人的 +
    + {/*双层*/} + + + {visibles === true ? + this.cancelModulationModels()} + /> : "" + } - { - homework_status&&homework_status.length===0? -
    - -
    - : - homework_status&&homework_status.length>0 && homework_status&&homework_status[0]==="未发布"? -
    - -
    - : -
    + { + homework_status&&homework_status.length===0? +
    + +
    + : + homework_status&&homework_status.length>0 && homework_status&&homework_status[0]==="未发布"? +
    + +
    + : +
    -
    - + - {computeTimetype===false?
  • - - + {computeTimetype===false?
  • + + 正在执行成绩计算,完成后将为您自动刷新结果。温馨提示:执行时间因作品数量而异 -
  • :""} + :""} - -
    - {data === undefined ? "" :
    } - - {JSON.stringify(datas) !== "[]" ? -
    -
    +
    + {data === undefined ? "" :
    } + + {JSON.stringify(datas) !== "[]" ? +
    +
    +
    -
    {teacherdata === undefined ? "0" : teacherdata.commit_count === undefined ? "0" : teacherdata.commit_count} @@ -3761,8 +3761,8 @@ class Listofworksstudentone extends Component { style={{color: '#FF6800'}}>{teacherdata.left_time.time}} - -
    - - {/*计算成绩时间:{teacherdata&&teacherdata.calculation_time==null?"--": moment(teacherdata&&teacherdata.calculation_time).format('YYYY-MM-DD HH:mm')}*/} - {/* { course_is_end===true?"":teacherdata&&teacherdata.task_operation&&teacherdata.task_operation[0]==="开启挑战"?"":*/} - {/* {computeTimetype===true?*/} - - {/* (this.props.isNotMember()===false?*/} - {/* (*/} - {/* teacherdata&&teacherdata.update_score===true?*/} - {/*
    */} - {/* 查看最新成绩*/} - {/*
    :""*/} - {/* )*/} - {/* :""):*/} - {/* teacherdata&&teacherdata.homework_status!==undefined&&teacherdata.homework_status[0]=== "未发布"? "":*/} - {/* (this.props.isNotMember()===false?
    */} - {/* 查看最新成绩*/} - {/*
    :"")*/} - {/* }*/} - {/*
    }*/} -
    + +
    + + {/*计算成绩时间:{teacherdata&&teacherdata.calculation_time==null?"--": moment(teacherdata&&teacherdata.calculation_time).format('YYYY-MM-DD HH:mm')}*/} + {/* { course_is_end===true?"":teacherdata&&teacherdata.task_operation&&teacherdata.task_operation[0]==="开启挑战"?"":*/} + {/* {computeTimetype===true?*/} + + {/* (this.props.isNotMember()===false?*/} + {/* (*/} + {/* teacherdata&&teacherdata.update_score===true?*/} + {/*
    */} + {/* 查看最新成绩*/} + {/*
    :""*/} + {/* )*/} + {/* :""):*/} + {/* teacherdata&&teacherdata.homework_status!==undefined&&teacherdata.homework_status[0]=== "未发布"? "":*/} + {/* (this.props.isNotMember()===false?
    */} + {/* 查看最新成绩*/} + {/*
    :"")*/} + {/* }*/} + {/*
    }*/}
    -
    - -
    - {datas === undefined ? "" :
    } - +
    + {datas === undefined ? "" :
    } - { - teacherdata && teacherdata.work_count && teacherdata.work_count > limit ? -
    - -
    - : "" - } - : -
    -
    -
    - -

    暂时还没有相关数据哦!

    + { + teacherdata && teacherdata.work_count && teacherdata.work_count > limit ? +
    +
    + : "" + } +
    + : +
    +
    +
    + +

    暂时还没有相关数据哦!

    - } -
    +
    + }
    - } + } + } From 29b068c8d3468c901fd9cfe0f9b96f3372ef5240 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Sat, 12 Oct 2019 17:15:18 +0800 Subject: [PATCH 054/252] b --- public/react/src/modules/login/Otherlogin.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/public/react/src/modules/login/Otherlogin.js b/public/react/src/modules/login/Otherlogin.js index 3c27e0e96..8c482c6b4 100644 --- a/public/react/src/modules/login/Otherlogin.js +++ b/public/react/src/modules/login/Otherlogin.js @@ -21,7 +21,6 @@ import { Spin } from "antd"; import axios from 'axios'; -const { Header, Footer, Sider, Content } = Layout; import { getImageUrl } from 'educoder' import {Link, Switch, Route, Redirect} from 'react-router-dom'; import '../courses/css/members.css'; @@ -29,7 +28,7 @@ import "../courses/common/formCommon.css" import '../courses/css/Courses.css'; import beijintulogontwo from '../../../src/images/login/beijintulogontwo.png'; import educodernet from '../../../src/images/login/educodernet.png'; - +const { Header, Footer, Sider, Content } = Layout; //educoder登入页面 var sectionStyle = { "height": "100%", From 4fc5c52d28e9e45bb7bb148fe49938eb3367088a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Sat, 12 Oct 2019 17:24:49 +0800 Subject: [PATCH 055/252] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/AppConfig.js | 20 +++++++++---------- public/react/src/modules/login/LoginDialog.js | 4 ++-- .../modules/user/LoginRegisterComponent.js | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/public/react/src/AppConfig.js b/public/react/src/AppConfig.js index e1d5da561..98571d818 100644 --- a/public/react/src/AppConfig.js +++ b/public/react/src/AppConfig.js @@ -21,16 +21,16 @@ let hashTimeout // TODO 开发期多个身份切换 let debugType ="" -if (isDev) { - const _search = window.location.search; - let parsed = {}; - if (_search) { - parsed = queryString.parse(_search); - } - debugType = window.location.search.indexOf('debug=t') != -1 ? 'teacher' : - window.location.search.indexOf('debug=s') != -1 ? 'student' : - window.location.search.indexOf('debug=a') != -1 ? 'admin' : parsed.debug || 'admin' -} +// if (isDev) { +// const _search = window.location.search; +// let parsed = {}; +// if (_search) { +// parsed = queryString.parse(_search); +// } +// debugType = window.location.search.indexOf('debug=t') != -1 ? 'teacher' : +// window.location.search.indexOf('debug=s') != -1 ? 'student' : +// window.location.search.indexOf('debug=a') != -1 ? 'admin' : parsed.debug || 'admin' +// } window._debugType = debugType; export function initAxiosInterceptors(props) { initOnlineOfflineListener() diff --git a/public/react/src/modules/login/LoginDialog.js b/public/react/src/modules/login/LoginDialog.js index ae7d781e9..b15518a4f 100644 --- a/public/react/src/modules/login/LoginDialog.js +++ b/public/react/src/modules/login/LoginDialog.js @@ -524,7 +524,7 @@ class LoginDialog extends Component { if (isRender === undefined) { isRender = false } - + console.log(this.props) return ( :""} + src={`https://open.weixin.qq.com/connect/qrconnect?appid=wx6b119e2d829c13fa&redirect_uri=https%3a%2f%2f${window.location.host}%2fotherloginstart&response_type=code&scope=snsapi_login#wechat_redirect`}>:""} {weixinlogin===true?

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

    :""} diff --git a/public/react/src/modules/user/LoginRegisterComponent.js b/public/react/src/modules/user/LoginRegisterComponent.js index fedc3cb22..978682e0b 100644 --- a/public/react/src/modules/user/LoginRegisterComponent.js +++ b/public/react/src/modules/user/LoginRegisterComponent.js @@ -1192,7 +1192,7 @@ class LoginRegisterComponent extends Component { frameBorder="0" sandbox="allow-scripts allow-same-origin allow-top-navigation" scrolling="no" - src="https://open.weixin.qq.com/connect/qrconnect?appid=wx6b119e2d829c13fa&redirect_uri=https%3a%2f%2fwww.educoder.net%2fotherloginstart&response_type=code&scope=snsapi_login#wechat_redirect">:""} + src={`https://open.weixin.qq.com/connect/qrconnect?appid=wx6b119e2d829c13fa&redirect_uri=https%3a%2f%2f${window.location.host}%2fotherloginstart&response_type=code&scope=snsapi_login#wechat_redirect`}>:""} {weixinlogin===true?

    this.hideweixinlogin()}>返回登录注册

    :""} From c7842cf16fdfa728298dae051dc68ca81a96d3a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Sat, 12 Oct 2019 17:31:30 +0800 Subject: [PATCH 056/252] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/modules/login/Otherloginstart.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/react/src/modules/login/Otherloginstart.js b/public/react/src/modules/login/Otherloginstart.js index 4b134805d..9b38ea2b9 100644 --- a/public/react/src/modules/login/Otherloginstart.js +++ b/public/react/src/modules/login/Otherloginstart.js @@ -16,7 +16,7 @@ class Otherloginstart extends Component { }}).then((result)=> { if(result){ if(result.data.status===0){ - if(result.data.true===false){ + if(result.data.new_user===true){ window.location.href="/otherlogin" }else{ // this.getinfo() From dfce76d4d51a3fe34c5f3bad2bf7f82e430935a0 Mon Sep 17 00:00:00 2001 From: p31729568 Date: Sat, 12 Oct 2019 17:32:14 +0800 Subject: [PATCH 057/252] fix --- app/forms/users/update_password_form.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/forms/users/update_password_form.rb b/app/forms/users/update_password_form.rb index 023caa40f..4da341839 100644 --- a/app/forms/users/update_password_form.rb +++ b/app/forms/users/update_password_form.rb @@ -4,5 +4,4 @@ class Users::UpdatePasswordForm attr_accessor :password, :old_password validates :password, presence: true - validates :old_password, presence: true end \ No newline at end of file From 7506145c8764ce069f83562b68808c8939fd2dcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Sat, 12 Oct 2019 17:41:02 +0800 Subject: [PATCH 058/252] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/modules/login/Otherlogin.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/public/react/src/modules/login/Otherlogin.js b/public/react/src/modules/login/Otherlogin.js index 8c482c6b4..b6a465199 100644 --- a/public/react/src/modules/login/Otherlogin.js +++ b/public/react/src/modules/login/Otherlogin.js @@ -181,9 +181,20 @@ class Otherlogin extends Component {
    -
    +
    +
    - +
    为了更好的为您服务,请关联一个EduCoder账号 From 5344295adfb41c33f55edc7aa94fe068ddb36fb0 Mon Sep 17 00:00:00 2001 From: daiao <358551898@qq.com> Date: Sat, 12 Oct 2019 17:49:44 +0800 Subject: [PATCH 059/252] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E7=99=BB=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/bind_users_controller.rb | 2 +- app/services/create_bind_user_service.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/bind_users_controller.rb b/app/controllers/bind_users_controller.rb index 530aa9b73..354b2993b 100644 --- a/app/controllers/bind_users_controller.rb +++ b/app/controllers/bind_users_controller.rb @@ -17,6 +17,6 @@ class BindUsersController < ApplicationController private def create_params - params.permit(:login, :password, :type, :not_bind) + params.permit(:username, :password, :type, :not_bind) end end \ No newline at end of file diff --git a/app/services/create_bind_user_service.rb b/app/services/create_bind_user_service.rb index 29818c493..a6ec9f163 100644 --- a/app/services/create_bind_user_service.rb +++ b/app/services/create_bind_user_service.rb @@ -15,7 +15,7 @@ class CreateBindUserService < ApplicationService return user end - bind_user = User.try_to_login(params[:login], params[:password]) + bind_user = User.try_to_login(params[:username], params[:password]) raise Error, '用户名或者密码错误' if bind_user.blank? ActiveRecord::Base.transaction do From e7af04ac2615db27d2f7cc3e980e4220920cfed7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Sat, 12 Oct 2019 18:00:16 +0800 Subject: [PATCH 060/252] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/modules/login/Otherlogin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/react/src/modules/login/Otherlogin.js b/public/react/src/modules/login/Otherlogin.js index b6a465199..b90889d78 100644 --- a/public/react/src/modules/login/Otherlogin.js +++ b/public/react/src/modules/login/Otherlogin.js @@ -194,7 +194,7 @@ class Otherlogin extends Component { }
    - + {data===undefined?"":data.image_url===undefined||data.image_url===null||data.image_url===""?"":}
    为了更好的为您服务,请关联一个EduCoder账号 From 79a71d9430bbb7ddd969608ca3e2074d353138dd Mon Sep 17 00:00:00 2001 From: daiao <358551898@qq.com> Date: Sat, 12 Oct 2019 18:04:23 +0800 Subject: [PATCH 061/252] =?UTF-8?q?=E5=A4=96=E9=94=AE=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/user.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/user.rb b/app/models/user.rb index 11ffe084c..0bebe8584 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -43,7 +43,7 @@ class User < ApplicationRecord has_many :myshixuns, :dependent => :destroy has_many :study_shixuns, through: :myshixuns, source: :shixun # 已学习的实训 has_many :course_messages - has_many :courses, dependent: :destroy + has_many :courses, foreign_key: 'tea_id', dependent: :destroy #试卷 has_many :exercise_banks, :dependent => :destroy From 4569ade2065613a052e585e6c14a954f85f45c00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Sat, 12 Oct 2019 18:06:00 +0800 Subject: [PATCH 062/252] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/AppConfig.js | 20 ++++++++++---------- public/react/src/modules/login/Otherlogin.js | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/public/react/src/AppConfig.js b/public/react/src/AppConfig.js index 98571d818..e1d5da561 100644 --- a/public/react/src/AppConfig.js +++ b/public/react/src/AppConfig.js @@ -21,16 +21,16 @@ let hashTimeout // TODO 开发期多个身份切换 let debugType ="" -// if (isDev) { -// const _search = window.location.search; -// let parsed = {}; -// if (_search) { -// parsed = queryString.parse(_search); -// } -// debugType = window.location.search.indexOf('debug=t') != -1 ? 'teacher' : -// window.location.search.indexOf('debug=s') != -1 ? 'student' : -// window.location.search.indexOf('debug=a') != -1 ? 'admin' : parsed.debug || 'admin' -// } +if (isDev) { + const _search = window.location.search; + let parsed = {}; + if (_search) { + parsed = queryString.parse(_search); + } + debugType = window.location.search.indexOf('debug=t') != -1 ? 'teacher' : + window.location.search.indexOf('debug=s') != -1 ? 'student' : + window.location.search.indexOf('debug=a') != -1 ? 'admin' : parsed.debug || 'admin' +} window._debugType = debugType; export function initAxiosInterceptors(props) { initOnlineOfflineListener() diff --git a/public/react/src/modules/login/Otherlogin.js b/public/react/src/modules/login/Otherlogin.js index b90889d78..6e240ece0 100644 --- a/public/react/src/modules/login/Otherlogin.js +++ b/public/react/src/modules/login/Otherlogin.js @@ -194,7 +194,7 @@ class Otherlogin extends Component { }
    - {data===undefined?"":data.image_url===undefined||data.image_url===null||data.image_url===""?"":} + {data===undefined?"":data.image_url===undefined||data.image_url===null||data.image_url===""?"":}
    为了更好的为您服务,请关联一个EduCoder账号 From 53a449728fc19138a668fda2949531a1009a541e Mon Sep 17 00:00:00 2001 From: p31729568 Date: Sat, 12 Oct 2019 18:32:58 +0800 Subject: [PATCH 063/252] fix bind user bug --- app/services/create_bind_user_service.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/services/create_bind_user_service.rb b/app/services/create_bind_user_service.rb index a6ec9f163..5455b7561 100644 --- a/app/services/create_bind_user_service.rb +++ b/app/services/create_bind_user_service.rb @@ -22,7 +22,8 @@ class CreateBindUserService < ApplicationService open_user.user_id = bind_user.id open_user.save! - user.destroy! + user.user_extension.delete + user.delete end clear_can_bind_user_flag From 10609006227d6ddb34dc03de6271693b26617eba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Sun, 13 Oct 2019 12:35:49 +0800 Subject: [PATCH 064/252] =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=89=8B=E6=9C=BA?= =?UTF-8?q?=E7=AB=AF=20=E5=BE=AE=E4=BF=A1=E7=99=BB=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/modules/login/LoginDialog.js | 36 +++++++++++++++++-- .../modules/paths/PathDetail/DetailCards.js | 13 +++---- public/react/src/modules/tpm/TPMBanner.js | 2 +- .../src/modules/tpm/TPMFork/TPMForklist.js | 2 +- .../src/modules/tpm/shixuns/ShixunCard.js | 2 +- .../modules/user/LoginRegisterComponent.js | 28 ++++++++++++--- 6 files changed, 66 insertions(+), 17 deletions(-) diff --git a/public/react/src/modules/login/LoginDialog.js b/public/react/src/modules/login/LoginDialog.js index b15518a4f..3f5afd845 100644 --- a/public/react/src/modules/login/LoginDialog.js +++ b/public/react/src/modules/login/LoginDialog.js @@ -349,8 +349,25 @@ class LoginDialog extends Component { // console.log(nextProps.isRender); } - + IsPC=()=>{ + var userAgentInfo = navigator.userAgent; + var Agents = ["Android", "iPhone", + "SymbianOS", "Windows Phone", + "iPad", "iPod"]; + var flag = true; + for (var v = 0; v < Agents.length; v++) { + if (userAgentInfo.indexOf(Agents[v]) > 0) { + flag = false; + break; + } + } + return flag; + } componentDidMount() { + let flag = this.IsPC(); //true为PC端,false为手机端 + this.setState({ + isphone:flag + }) if(this.props.isRender!=undefined){ this.setState({ @@ -536,6 +553,19 @@ class LoginDialog extends Component { modalsType={this.state.MyEduCoderModals} setNotcompleteds={()=>{this.setNotcompleteds()}} /> + + {this.state.isphone===false?:""} {isRender===true?
    {this.handleDialogClose()}}> @@ -622,7 +652,7 @@ class LoginDialog extends Component {

    -

    + {this.state.isphone===true?

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

    @@ -630,7 +660,7 @@ class LoginDialog extends Component { 微信登录
    -

    +

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