Merge branches 'dev_aliyun' and 'topic_bank' of https://bdgit.educoder.net/Hjqreturn/educoder into topic_bank
	
		
	
				
					
				
			
						commit
						3a445e8159
					
				| @ -0,0 +1,2 @@ | ||||
| // Place all the behaviors and hooks related to the matching controller here.
 | ||||
| // All this logic will automatically be available in application.js.
 | ||||
| @ -0,0 +1,3 @@ | ||||
| // Place all the styles related to the homework_banks controller here. | ||||
| // They will automatically be included in application.css. | ||||
| // You can use Sass (SCSS) here: http://sass-lang.com/ | ||||
| @ -0,0 +1,60 @@ | ||||
| #encoding: UTF-8 | ||||
| class ExerciseBanksController < ApplicationController | ||||
|   before_action :require_login | ||||
|   before_action :find_bank | ||||
|   before_action :bank_admin, only: [:update] | ||||
| 
 | ||||
|   def show | ||||
|     @exercise_questions = @bank.exercise_bank_questions&.includes(:exercise_bank_choices, :exercise_bank_shixun_challenges, | ||||
|                                                                   :exercise_bank_standard_answers).order("question_number ASC") | ||||
|     @exercise_ques_count = @exercise_questions.size # 全部的题目数 | ||||
|     @exercise_ques_scores = @exercise_questions.pluck(:question_score).sum | ||||
| 
 | ||||
|     #单选题的数量及分数 | ||||
|     exercise_single_ques = @exercise_questions.find_by_custom("question_type", Exercise::SINGLE) | ||||
|     @exercise_single_ques_count = exercise_single_ques.size | ||||
|     @exercise_single_ques_scores = exercise_single_ques.pluck(:question_score).sum | ||||
| 
 | ||||
|     #多选题的数量及分数 | ||||
|     exercise_double_ques = @exercise_questions.find_by_custom("question_type", Exercise::MULTIPLE) | ||||
|     @exercise_double_ques_count = exercise_double_ques.size | ||||
|     @exercise_double_ques_scores = exercise_double_ques.pluck(:question_score).sum | ||||
| 
 | ||||
|     # 判断题数量及分数 | ||||
|     exercise_ques_judge = @exercise_questions.find_by_custom("question_type", Exercise::JUDGMENT) | ||||
|     @exercise_ques_judge_count = exercise_ques_judge.size | ||||
|     @exercise_ques_judge_scores = exercise_ques_judge.pluck(:question_score).sum | ||||
| 
 | ||||
|     #填空题数量及分数 | ||||
|     exercise_ques_null = @exercise_questions.find_by_custom("question_type", Exercise::COMPLETION) | ||||
|     @exercise_ques_null_count = exercise_ques_null.size | ||||
|     @exercise_ques_null_scores = exercise_ques_null.pluck(:question_score).sum | ||||
| 
 | ||||
|     #简答题数量及分数 | ||||
|     exercise_ques_main = @exercise_questions.find_by_custom("question_type", Exercise::SUBJECTIVE) | ||||
|     @exercise_ques_main_count = exercise_ques_main.size | ||||
|     @exercise_ques_main_scores = exercise_ques_main.pluck(:question_score).sum | ||||
| 
 | ||||
|     #实训题数量及分数 | ||||
|     exercise_ques_shixun = @exercise_questions.find_by_custom("question_type", Exercise::PRACTICAL) | ||||
|     @exercise_ques_shixun_count = exercise_ques_shixun.size | ||||
|     @exercise_ques_shixun_scores = exercise_ques_shixun.pluck(:question_score).sum | ||||
|   end | ||||
| 
 | ||||
|   def update | ||||
|     tip_exception("试卷标题不能为空!") if params[:exercise_name].blank? | ||||
|     @bank.update_attributes!(name: params[:exercise_name], description: params[:exercise_description]) | ||||
|     normal_status(0,"试卷更新成功!") | ||||
|   end | ||||
| 
 | ||||
|   private | ||||
| 
 | ||||
|   def find_bank | ||||
|     @bank = ExerciseBank.find_by!(id: params[:id]) | ||||
|     tip_exception(403, "无权限") unless (current_user.certification_teacher? && (@bank.is_public || @bank.user_id == current_user.id)) || current_user.admin? | ||||
|   end | ||||
| 
 | ||||
|   def bank_admin | ||||
|     tip_exception(403, "无权限") unless (current_user.certification_teacher? && @bank.user_id == current_user.id) || current_user.admin? | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,39 @@ | ||||
| class GtopicBanksController < ApplicationController | ||||
|   before_action :require_login | ||||
|   before_action :find_bank | ||||
|   before_action :bank_admin, only: [:edit, :update] | ||||
| 
 | ||||
|   def show | ||||
|     @bank_attachments = @bank.attachments | ||||
|   end | ||||
| 
 | ||||
|   def edit | ||||
|     @attachments = @bank.attachments | ||||
|   end | ||||
| 
 | ||||
|   def update | ||||
|     ActiveRecord::Base.transaction do | ||||
|       @bank.update_attributes(gtopic_bank_params) | ||||
|       Attachment.associate_container(params[:attachment_ids], @bank.id, @bank.class) if params[:attachment_ids] | ||||
|       normal_status(0, "更新成功") | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   private | ||||
| 
 | ||||
|   def find_bank | ||||
|     @bank = GtopicBank.find_by!(id: params[:id]) | ||||
|     tip_exception(403, "无权限") unless (current_user.certification_teacher? && (@bank.is_public || @bank.user_id == current_user.id)) || current_user.admin? | ||||
|   end | ||||
| 
 | ||||
|   def bank_admin | ||||
|     tip_exception(403, "无权限") unless (current_user.certification_teacher? && @bank.user_id == current_user.id) || current_user.admin? | ||||
|   end | ||||
| 
 | ||||
|   def gtopic_bank_params | ||||
|     tip_exception("name参数不能为空") if params[:gtopic_bank][:name].blank? | ||||
|     tip_exception("description参数不能为空") if params[:gtopic_bank][:description].blank? | ||||
|     params.require(:gtopic_bank).permit(:name, :topic_type, :topic_source, :topic_property_first, :description, | ||||
|                                         :topic_property_second, :source_unit, :topic_repeat, :province, :city) | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,63 @@ | ||||
| class HomeworkBanksController < ApplicationController | ||||
|   before_action :require_login | ||||
|   before_action :find_bank | ||||
|   before_action :bank_params, only: [:update] | ||||
|   before_action :bank_admin, only: [:update, :destroy, :set_public] | ||||
| 
 | ||||
|   def show | ||||
|     @bank_attachments = @bank.attachments.where(attachtype: 1) | ||||
|     @reference_attachments = @bank.attachments.where(attachtype: 2) | ||||
|   end | ||||
| 
 | ||||
|   def update | ||||
|     ActiveRecord::Base.transaction do | ||||
|       @bank.update_attributes(name: params[:name], description: params[:description], reference_answer: params[:reference_answer]) | ||||
| 
 | ||||
|       # 作业描述的附件 | ||||
|       Attachment.associate_container(params[:attachment_ids], @bank.id, @bank.class) if params[:attachment_ids] | ||||
|       # 作业参考答案的附件 | ||||
|       Attachment.associate_container(params[:reference_attachment_ids], @bank.id, @bank.class, 2) if params[:reference_attachment_ids] | ||||
| 
 | ||||
|       normal_status(0, "更新成功") | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   def destroy | ||||
|     ActiveRecord::Base.transaction do | ||||
|       @bank.homework_commons.update_all(homework_bank_id: nil) | ||||
|       @bank.destroy! | ||||
|       normal_status("删除成功") | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   def set_public | ||||
|     @bank.update_attributes(is_public: 1) | ||||
|     normal_status("更新成功") | ||||
|   end | ||||
| 
 | ||||
|   private | ||||
| 
 | ||||
|   def find_bank | ||||
|     @bank = HomeworkBank.find_by!(id: params[:id]) | ||||
|     tip_exception(403, "无权限") unless (current_user.certification_teacher? && (@bank.is_public || @bank.user_id == current_user.id)) || current_user.admin? | ||||
|   end | ||||
| 
 | ||||
|   def bank_admin | ||||
|     tip_exception(403, "无权限") unless (current_user.certification_teacher? && @bank.user_id == current_user.id) || current_user.admin? | ||||
|   end | ||||
| 
 | ||||
|   def bank_params | ||||
|     tip_exception("name参数不能为空") if params[:homework_bank][:name].blank? | ||||
|     tip_exception("description参数不能为空") if params[:homework_bank][:description].blank? | ||||
|     if @bank.homework_type == 3 | ||||
|       tip_exception("base_on_project参数不能为空") if params[:homework_bank][:base_on_project].nil? | ||||
|       tip_exception("min_num参数不能为空") if params[:homework_bank][:min_num].blank? | ||||
|       tip_exception("max_num参数不能为空") if params[:homework_bank][:max_num].blank? | ||||
|       tip_exception("最小人数不能小于1") if params[:homework_bank][:min_num].to_i < 1 | ||||
|       tip_exception("最大人数不能小于最小人数") if params[:homework_bank][:max_num].to_i < params[:homework_bank][:min_num].to_i | ||||
|     end | ||||
|     params.require(:homework_bank).permit(:name, :description, :reference_answer) if @bank.homework_type == 1 | ||||
|     params.require(:homework_bank).permit(:name, :description, :reference_answer, :min_num, :max_num, :base_on_project) if @bank.homework_type == 3 | ||||
|   end | ||||
| 
 | ||||
| end | ||||
| @ -0,0 +1,48 @@ | ||||
| class TaskBanksController < ApplicationController | ||||
|   before_action :require_login | ||||
|   before_action :find_bank | ||||
|   before_action :bank_admin, only: [:update] | ||||
| 
 | ||||
|   def show | ||||
|     @bank_attachments = @bank.attachments | ||||
|   end | ||||
| 
 | ||||
|   def update | ||||
|     ActiveRecord::Base.transaction do | ||||
|       begin | ||||
|         @bank.update_attributes(gtask_bank_params) | ||||
|         Attachment.associate_container(params[:attachment_ids], @bank.id, @bank.class) if params[:attachment_ids] | ||||
|         normal_status(0, "更新成功") | ||||
|       rescue Exception => e | ||||
|         uid_logger(e.message) | ||||
|         tip_exception(e.message) | ||||
|         raise ActiveRecord::Rollback | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   private | ||||
| 
 | ||||
|   def find_bank | ||||
|     @bank = GtaskBank.find_by!(id: params[:id]) | ||||
|     tip_exception(403, "无权限") unless (current_user.certification_teacher? && (@bank.is_public || @bank.user_id == current_user.id)) || current_user.admin? | ||||
|   end | ||||
| 
 | ||||
|   def bank_admin | ||||
|     tip_exception(403, "无权限") unless (current_user.certification_teacher? && @bank.user_id == current_user.id) || current_user.admin? | ||||
|   end | ||||
| 
 | ||||
|   def gtask_bank_params | ||||
|     tip_exception("name参数不能为空") if params[:gtask_bank][:name].blank? | ||||
|     tip_exception("description参数不能为空") if params[:gtask_bank][:description].blank? | ||||
|     if @bank.homework_type == 3 | ||||
|       tip_exception("base_on_project参数不能为空") if params[:gtask_bank][:base_on_project].nil? | ||||
|       tip_exception("min_num参数不能为空") if params[:gtask_bank][:min_num].blank? | ||||
|       tip_exception("max_num参数不能为空") if params[:gtask_bank][:max_num].blank? | ||||
|       tip_exception("最小人数不能小于1") if params[:gtask_bank][:min_num].to_i < 1 | ||||
|       tip_exception("最大人数不能小于最小人数") if params[:gtask_bank][:max_num].to_i < params[:gtask_bank][:min_num].to_i | ||||
|     end | ||||
|     params.require(:gtask_bank).permit(:name, :description) if @bank.task_type == 1 | ||||
|     params.require(:gtask_bank).permit(:name, :description, :min_num, :max_num, :base_on_project) if @bank.task_type == 2 | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,2 @@ | ||||
| module ExerciseBankQuestionsHelper | ||||
| end | ||||
| @ -0,0 +1,2 @@ | ||||
| module HomeworkBanksHelper | ||||
| end | ||||
| @ -1,4 +1,7 @@ | ||||
| class ExerciseBankChoice < ApplicationRecord | ||||
|   belongs_to :exercise_bank_question | ||||
|   has_many :exercise_bank_standard_answers | ||||
| 
 | ||||
|   scope :find_choice_custom, lambda {|k,v| where("#{k} = ?",v)}  #根据传入的参数查找问题 | ||||
|   scope :left_choice_choose, lambda {|k,v| where("#{k} > ?",v)}  #根据传入的参数查找问题 | ||||
| end | ||||
| @ -0,0 +1,29 @@ | ||||
| wb = xlsx_package.workbook | ||||
| wb.use_shared_strings = true | ||||
| wb.styles do |s| | ||||
|   no_wrap_sz = s.add_style :border => { :style => :thin, :color =>"000000" },:alignment => {wrap_text: false,:horizontal => :center,:vertical => :center } | ||||
|   sz_all = s.add_style :border => { :style => :thin, :color =>"000000" },:alignment => {wrap_text: true,:horizontal => :center,:vertical => :center } | ||||
|   row_cell = s.add_style :bg_color=> "FAEBDC",:border => { :style => :thin, :color =>"000000" },alignment: {wrap_text: true,:horizontal => :center,:vertical => :center } | ||||
|   blue_cell = s.add_style :bg_color => "FAEBDC", :sz => 10,:height => 25,:b => true, :border => { :style => :thin, :color =>"000000" },:alignment => {wrap_text: true,:horizontal => :center,:vertical => :center} | ||||
| 
 | ||||
|   #课堂信息摘要 | ||||
|   wb.add_worksheet(name:course_info[0]) do |sheet| | ||||
|     sheet.sheet_view.show_grid_lines = false | ||||
|     course_main_info = course_info[1] | ||||
|     course_group_info = course_info[2] | ||||
|     group_info_d = course_group_info[0] | ||||
|     group_info_detail = course_group_info[1] | ||||
|     course_main_info.each do |c| | ||||
|       sheet.add_row c, :style => sz_all  #用户id | ||||
|     end | ||||
|     sheet["A1:A7"].each { |c| c.style = row_cell } | ||||
|     sheet.add_row [],:style => sz_all | ||||
|     if group_info_detail.count > 0 | ||||
|       sheet.add_row group_info_d, :style => blue_cell | ||||
|       group_info_detail.each do |group| | ||||
|         sheet.add_row group, :style => sz_all  #用户id | ||||
|       end | ||||
|       sheet.column_info.second.width = 40 | ||||
|     end | ||||
|   end  #add_worksheet | ||||
| end | ||||
| @ -0,0 +1,25 @@ | ||||
| wb = xlsx_package.workbook | ||||
| wb.use_shared_strings = true | ||||
| wb.styles do |s| | ||||
|   no_wrap_sz = s.add_style :border => { :style => :thin, :color =>"000000" },:alignment => {wrap_text: false,:horizontal => :center,:vertical => :center } | ||||
|   sz_all = s.add_style :border => { :style => :thin, :color =>"000000" },:alignment => {wrap_text: true,:horizontal => :center,:vertical => :center } | ||||
|   row_cell = s.add_style :bg_color=> "FAEBDC",:border => { :style => :thin, :color =>"000000" },alignment: {wrap_text: true,:horizontal => :center,:vertical => :center } | ||||
|   blue_cell = s.add_style :bg_color => "FAEBDC", :sz => 10,:height => 25,:b => true, :border => { :style => :thin, :color =>"000000" },:alignment => {wrap_text: true,:horizontal => :center,:vertical => :center} | ||||
| 
 | ||||
|   #课堂活跃度统计 | ||||
|   wb.add_worksheet(name:activity_level[0]) do |sheet| | ||||
|     sheet.sheet_view.show_grid_lines = false | ||||
|     sheet_title = activity_level[1] | ||||
|     sheet_content = activity_level[2] | ||||
|     sheet.add_row sheet_title, :height => 25,:style => blue_cell | ||||
|     if sheet_content.count > 0 | ||||
|       sheet_content.each_with_index do |c,index| | ||||
|         c_1 = (index+1) | ||||
|         c_2 = [c_1] + c.values | ||||
|         sheet.add_row c_2, :height => 25, :style => sz_all  #用户id | ||||
|       end | ||||
|       sheet.column_widths *([20]*sheet.column_info.count) | ||||
|       sheet.column_info.first.width = 8 | ||||
|     end | ||||
|   end  #add_worksheet | ||||
| end | ||||
| @ -0,0 +1,16 @@ | ||||
| json.exercise do | ||||
|   json.extract! @bank, :id, :name, :description, :is_public | ||||
| end | ||||
| 
 | ||||
| json.partial! "exercises/exercise_scores" | ||||
| 
 | ||||
| json.exercise_questions do | ||||
|   json.array! @exercise_questions do |q| | ||||
|     json.partial! "exercise_bank_questions/exercise_bank_questions", | ||||
|                   question: q, | ||||
|                   choices:q.exercise_bank_choices, | ||||
|                   shixun_challenges: q.exercise_bank_shixun_challenges, | ||||
|                   ques_position:nil, | ||||
|                   edit_type:nil | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,15 @@ | ||||
| json.topic_type topic_type | ||||
| json.topic_source topic_source | ||||
| json.topic_property_first topic_property_first | ||||
| json.topic_property_second topic_property_second | ||||
| json.topic_repeat topic_repeat | ||||
| 
 | ||||
| json.selected_data do | ||||
|   json.(@bank, :name, :topic_type, :topic_source, :topic_property_first, | ||||
|     :description, :topic_property_second, :source_unit, :topic_repeat, | ||||
|     :province, :city, :is_public) | ||||
| end | ||||
| 
 | ||||
| json.attachments @attachments do |attachment| | ||||
|   json.partial! "attachments/attachment_simple", locals: {attachment: attachment} | ||||
| end | ||||
| @ -0,0 +1,6 @@ | ||||
| json.(@bank, :id, :name, :description, :is_public, :topic_type, :topic_source, :topic_property_first, :topic_property_second, | ||||
|   :source_unit, :topic_repeat, :province, :city) | ||||
| 
 | ||||
| json.attachment_list @bank_attachments do |attachment| | ||||
|   json.partial! "attachments/attachment_simple", locals: {attachment: attachment} | ||||
| end | ||||
| @ -0,0 +1,9 @@ | ||||
| json.(@bank, :id, :name, :description, :homework_type, :is_public, :min_num, :max_num, :base_on_project, :reference_answer) | ||||
| 
 | ||||
| json.attachments @bank_attachments do |attachment| | ||||
|   json.partial! "attachments/attachment_simple", locals: {attachment: attachment} | ||||
| end | ||||
| 
 | ||||
| json.reference_attachments @reference_attachments do |attachment| | ||||
|   json.partial! "attachments/attachment_simple", locals: {attachment: attachment} | ||||
| end | ||||
| @ -0,0 +1,4 @@ | ||||
| json.courses @courses do |course| | ||||
|   json.course_id course.id | ||||
|   json.course_name course.name | ||||
| end | ||||
| @ -0,0 +1,14 @@ | ||||
| json.(@bank, :id, :name, :description, :task_type, :is_public) | ||||
| # 附件 | ||||
| json.attachments @bank_attachments do |attachment| | ||||
|   json.partial! "attachments/attachment_simple", locals: {attachment: attachment} | ||||
| end | ||||
| 
 | ||||
| # 分组要求 | ||||
| if @bank.task_type == 2 | ||||
|   json.group_info do | ||||
|     json.max_number @bank.max_num | ||||
|     json.min_number @bank.min_num | ||||
|     json.base_on_project @bank.base_on_project | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,5 @@ | ||||
| class AddIsOrderedToExerciseBankQuestion < ActiveRecord::Migration[5.2] | ||||
|   def change | ||||
|     add_column :exercise_bank_questions, :is_ordered, :boolean, :default => true | ||||
|   end | ||||
| end | ||||
| @ -1,189 +0,0 @@ | ||||
| 'use strict'; | ||||
| 
 | ||||
| // Do this as the first thing so that any code reading it knows the right env.
 | ||||
| process.env.BABEL_ENV = 'production'; | ||||
| process.env.NODE_ENV = 'production'; | ||||
| 
 | ||||
| // Makes the script crash on unhandled rejections instead of silently
 | ||||
| // ignoring them. In the future, promise rejections that are not handled will
 | ||||
| // terminate the Node.js process with a non-zero exit code.
 | ||||
| process.on('unhandledRejection', err => { | ||||
|   throw err; | ||||
| }); | ||||
| 
 | ||||
| // Ensure environment variables are read.
 | ||||
| require('../config/env'); | ||||
| 
 | ||||
| const path = require('path'); | ||||
| const chalk = require('chalk'); | ||||
| const fs = require('fs-extra'); | ||||
| const webpack = require('webpack'); | ||||
| const config = require('../config/webpack.config.prod'); | ||||
| const paths = require('../config/paths'); | ||||
| const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles'); | ||||
| const formatWebpackMessages = require('react-dev-utils/formatWebpackMessages'); | ||||
| const printHostingInstructions = require('react-dev-utils/printHostingInstructions'); | ||||
| const FileSizeReporter = require('react-dev-utils/FileSizeReporter'); | ||||
| const printBuildError = require('react-dev-utils/printBuildError'); | ||||
| 
 | ||||
| var CombinedStream = require('combined-stream'); | ||||
| var fs2 = require('fs'); | ||||
| 
 | ||||
| const measureFileSizesBeforeBuild = | ||||
|   FileSizeReporter.measureFileSizesBeforeBuild; | ||||
| const printFileSizesAfterBuild = FileSizeReporter.printFileSizesAfterBuild; | ||||
| const useYarn = fs.existsSync(paths.yarnLockFile); | ||||
| 
 | ||||
| // These sizes are pretty large. We'll warn for bundles exceeding them.
 | ||||
| const WARN_AFTER_BUNDLE_GZIP_SIZE = 512 * 1024; | ||||
| const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024; | ||||
| 
 | ||||
| // Warn and crash if required files are missing
 | ||||
| if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) { | ||||
|   process.exit(1); | ||||
| } | ||||
| 
 | ||||
| // First, read the current file sizes in build directory.
 | ||||
| // This lets us display how much they changed later.
 | ||||
| measureFileSizesBeforeBuild(paths.appBuild) | ||||
|   .then(previousFileSizes => { | ||||
|     // Remove all content but keep the directory so that
 | ||||
|     // if you're in it, you don't end up in Trash
 | ||||
|     fs.emptyDirSync(paths.appBuild); | ||||
|     // Merge with the public folder
 | ||||
|     copyPublicFolder(); | ||||
|     // Start the webpack build
 | ||||
|     return build(previousFileSizes); | ||||
|   }) | ||||
|   .then( | ||||
|     ({ stats, previousFileSizes, warnings }) => { | ||||
|       if (warnings.length) { | ||||
|         console.log(chalk.yellow('Compiled with warnings.\n')); | ||||
|         console.log(warnings.join('\n\n')); | ||||
|         console.log( | ||||
|           '\nSearch for the ' + | ||||
|             chalk.underline(chalk.yellow('keywords')) + | ||||
|             ' to learn more about each warning.' | ||||
|         ); | ||||
|         console.log( | ||||
|           'To ignore, add ' + | ||||
|             chalk.cyan('// eslint-disable-next-line') + | ||||
|             ' to the line before.\n' | ||||
|         ); | ||||
|       } else { | ||||
|         console.log(chalk.green('Compiled successfully.\n')); | ||||
|       } | ||||
| 
 | ||||
|       console.log('File sizes after gzip:\n'); | ||||
|       printFileSizesAfterBuild( | ||||
|         stats, | ||||
|         previousFileSizes, | ||||
|         paths.appBuild, | ||||
|         WARN_AFTER_BUNDLE_GZIP_SIZE, | ||||
|         WARN_AFTER_CHUNK_GZIP_SIZE | ||||
|       ); | ||||
|       console.log(); | ||||
| 
 | ||||
|       const appPackage = require(paths.appPackageJson); | ||||
|       const publicUrl = paths.publicUrl; | ||||
|       const publicPath = config.output.publicPath; | ||||
|       const buildFolder = path.relative(process.cwd(), paths.appBuild); | ||||
|       printHostingInstructions( | ||||
|         appPackage, | ||||
|         publicUrl, | ||||
|         publicPath, | ||||
|         buildFolder, | ||||
|         useYarn | ||||
|       ); | ||||
|     }, | ||||
|     err => { | ||||
|       console.log(chalk.red('Failed to compile.\n')); | ||||
|       printBuildError(err); | ||||
|       process.exit(1); | ||||
|     } | ||||
|   ); | ||||
| 
 | ||||
| // Create the production build and print the deployment instructions.
 | ||||
| function build(previousFileSizes) { | ||||
|   console.log('Creating an optimized production build...'); | ||||
| 
 | ||||
|   let compiler = webpack(config); | ||||
|   return new Promise((resolve, reject) => { | ||||
|     compiler.run((err, stats) => { | ||||
|       if (err) { | ||||
|         return reject(err); | ||||
|       } | ||||
|       const messages = formatWebpackMessages(stats.toJson({}, true)); | ||||
|       if (messages.errors.length) { | ||||
|         // Only keep the first error. Others are often indicative
 | ||||
|         // of the same problem, but confuse the reader with noise.
 | ||||
|         if (messages.errors.length > 1) { | ||||
|           messages.errors.length = 1; | ||||
|         } | ||||
|         return reject(new Error(messages.errors.join('\n\n'))); | ||||
|       } | ||||
|       if ( | ||||
|         process.env.CI && | ||||
|         (typeof process.env.CI !== 'string' || | ||||
|           process.env.CI.toLowerCase() !== 'false') && | ||||
|         messages.warnings.length | ||||
|       ) { | ||||
|         console.log( | ||||
|           chalk.yellow( | ||||
|             '\nTreating warnings as errors because process.env.CI = true.\n' + | ||||
|               'Most CI servers set it automatically.\n' | ||||
|           ) | ||||
|         ); | ||||
|         return reject(new Error(messages.warnings.join('\n\n'))); | ||||
|       } | ||||
| 
 | ||||
|       generateNewIndexJsp(); | ||||
| 
 | ||||
|       return resolve({ | ||||
|         stats, | ||||
|         previousFileSizes, | ||||
|         warnings: messages.warnings, | ||||
|       }); | ||||
|     }); | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| function copyPublicFolder() { | ||||
|   fs.copySync(paths.appPublic, paths.appBuild, { | ||||
|     dereference: true, | ||||
|     filter: file => file !== paths.appHtml, | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| function generateNewIndexJsp() { | ||||
|   // var combinedStream = CombinedStream.create();
 | ||||
|   var filePath = paths.appBuild + '/index.html'; | ||||
|   // var htmlContent = fs2.createReadStream( filePath )
 | ||||
| 
 | ||||
|   // stream没有replace方法
 | ||||
|   // htmlContent = htmlContent.replace('/js/js_min_all.js', '/react/build/js/js_min_all.js')
 | ||||
|   // htmlContent = htmlContent.replace('/css/css_min_all.css', '/react/build/css/css_min_all.css')
 | ||||
| 
 | ||||
|   // combinedStream.append(htmlContent);
 | ||||
|   // combinedStream.pipe(fs2.createWriteStream( filePath ));
 | ||||
| 
 | ||||
|   var outputPath = paths.appBuild  + '/../../../app/views/common/index.html.erb' | ||||
|   fs2.readFile(filePath, 'utf8', function (err,data) { | ||||
|     if (err) { | ||||
|       return console.log(err); | ||||
|     } | ||||
|     var result = data.replace('/js/js_min_all.js', '/react/build/js/js_min_all.js') | ||||
|         .replace('/js/js_min_all_2.js', '/react/build/js/js_min_all_2.js') | ||||
| 
 | ||||
|         .replace('/css/css_min_all.css', '/react/build/css/css_min_all.css') | ||||
|         .replace('/js/create_kindeditor.js', '/react/build/js/create_kindeditor.js') | ||||
|         .replace(/http:\/\/localhost:3000/g, ''); | ||||
| 
 | ||||
|         // .replace('/css/css_min_all.css', '/react/build/css/css_min_all.css');
 | ||||
| 
 | ||||
|     fs2.writeFile(outputPath, result, 'utf8', function (err) { | ||||
|        if (err) return console.log(err); | ||||
|     }); | ||||
|   }); | ||||
| } | ||||
| @ -1,114 +0,0 @@ | ||||
| 'use strict'; | ||||
| 
 | ||||
| // Do this as the first thing so that any code reading it knows the right env.
 | ||||
| process.env.BABEL_ENV = 'development'; | ||||
| process.env.NODE_ENV = 'development'; | ||||
| 
 | ||||
| 
 | ||||
| // Makes the script crash on unhandled rejections instead of silently
 | ||||
| // ignoring them. In the future, promise rejections that are not handled will
 | ||||
| // terminate the Node.js process with a non-zero exit code.
 | ||||
| process.on('unhandledRejection', err => { | ||||
|   throw err; | ||||
| }); | ||||
| 
 | ||||
| // Ensure environment variables are read.
 | ||||
| require('../config/env'); | ||||
| 
 | ||||
| const fs = require('fs'); | ||||
| const chalk = require('chalk'); | ||||
| const webpack = require('webpack'); | ||||
| const WebpackDevServer = require('webpack-dev-server'); | ||||
| const clearConsole = require('react-dev-utils/clearConsole'); | ||||
| const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles'); | ||||
| const { | ||||
|   choosePort, | ||||
|   createCompiler, | ||||
|   prepareProxy, | ||||
|   prepareUrls, | ||||
| } = require('react-dev-utils/WebpackDevServerUtils'); | ||||
| const openBrowser = require('react-dev-utils/openBrowser'); | ||||
| const paths = require('../config/paths'); | ||||
| const config = require('../config/webpack.config.dev'); | ||||
| const createDevServerConfig = require('../config/webpackDevServer.config'); | ||||
| 
 | ||||
| const useYarn = fs.existsSync(paths.yarnLockFile); | ||||
| const isInteractive = process.stdout.isTTY; | ||||
| 
 | ||||
| const portSetting = require(paths.appPackageJson).port | ||||
| if ( portSetting ) { | ||||
|   process.env.port = portSetting | ||||
| }  | ||||
| 
 | ||||
| // Warn and crash if required files are missing
 | ||||
| if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) { | ||||
|   process.exit(1); | ||||
| } | ||||
| 
 | ||||
| // Tools like Cloud9 rely on this.
 | ||||
| const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000; | ||||
| const HOST = process.env.HOST || '0.0.0.0'; | ||||
| 
 | ||||
| if (process.env.HOST) { | ||||
|   console.log( | ||||
|     chalk.cyan( | ||||
|       `Attempting to bind to HOST environment variable: ${chalk.yellow( | ||||
|         chalk.bold(process.env.HOST) | ||||
|       )}` | ||||
|     ) | ||||
|   ); | ||||
|   console.log( | ||||
|     `If this was unintentional, check that you haven't mistakenly set it in your shell.` | ||||
|   ); | ||||
|   console.log(`Learn more here: ${chalk.yellow('http://bit.ly/2mwWSwH')}`); | ||||
|   console.log(); | ||||
| } | ||||
| 
 | ||||
| // We attempt to use the default port but if it is busy, we offer the user to
 | ||||
| // run on a different port. `choosePort()` Promise resolves to the next free port.
 | ||||
| choosePort(HOST, DEFAULT_PORT) | ||||
|   .then(port => { | ||||
|     if (port == null) { | ||||
|       // We have not found a port.
 | ||||
|       return; | ||||
|     } | ||||
|     const protocol = process.env.HTTPS === 'true' ? 'https' : 'http'; | ||||
|     const appName = require(paths.appPackageJson).name; | ||||
|     const urls = prepareUrls(protocol, HOST, port); | ||||
|     // Create a webpack compiler that is configured with custom messages.
 | ||||
|     const compiler = createCompiler(webpack, config, appName, urls, useYarn); | ||||
|     // Load proxy config
 | ||||
|     const proxySetting = require(paths.appPackageJson).proxy; | ||||
|     console.log('-------------------------proxySetting:', proxySetting) | ||||
|     const proxyConfig = prepareProxy(proxySetting, paths.appPublic); | ||||
|     // Serve webpack assets generated by the compiler over a web sever.
 | ||||
|     const serverConfig = createDevServerConfig( | ||||
|       proxyConfig, | ||||
|       urls.lanUrlForConfig | ||||
|     ); | ||||
|     const devServer = new WebpackDevServer(compiler, serverConfig); | ||||
|     // Launch WebpackDevServer.
 | ||||
|     devServer.listen(port, HOST, err => { | ||||
|       if (err) { | ||||
|         return console.log(err); | ||||
|       } | ||||
|       if (isInteractive) { | ||||
|         clearConsole(); | ||||
|       } | ||||
|       console.log(chalk.cyan('Starting the development server...\n')); | ||||
|       openBrowser(urls.localUrlForBrowser); | ||||
|     }); | ||||
| 
 | ||||
|     ['SIGINT', 'SIGTERM'].forEach(function(sig) { | ||||
|       process.on(sig, function() { | ||||
|         devServer.close(); | ||||
|         process.exit(); | ||||
|       }); | ||||
|     }); | ||||
|   }) | ||||
|   .catch(err => { | ||||
|     if (err && err.message) { | ||||
|       console.log(err.message); | ||||
|     } | ||||
|     process.exit(1); | ||||
|   }); | ||||
| @ -1,27 +0,0 @@ | ||||
| 'use strict'; | ||||
| 
 | ||||
| // Do this as the first thing so that any code reading it knows the right env.
 | ||||
| process.env.BABEL_ENV = 'test'; | ||||
| process.env.NODE_ENV = 'test'; | ||||
| process.env.PUBLIC_URL = ''; | ||||
| 
 | ||||
| // Makes the script crash on unhandled rejections instead of silently
 | ||||
| // ignoring them. In the future, promise rejections that are not handled will
 | ||||
| // terminate the Node.js process with a non-zero exit code.
 | ||||
| process.on('unhandledRejection', err => { | ||||
|   throw err; | ||||
| }); | ||||
| 
 | ||||
| // Ensure environment variables are read.
 | ||||
| require('../config/env'); | ||||
| 
 | ||||
| const jest = require('jest'); | ||||
| const argv = process.argv.slice(2); | ||||
| 
 | ||||
| // Watch unless on CI or in coverage mode
 | ||||
| if (!process.env.CI && argv.indexOf('--coverage') < 0) { | ||||
|   argv.push('--watch'); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| jest.run(argv); | ||||
| @ -0,0 +1,5 @@ | ||||
| require 'rails_helper' | ||||
| 
 | ||||
| RSpec.describe HomeworkBanksController, type: :controller do | ||||
| 
 | ||||
| end | ||||
| @ -0,0 +1,15 @@ | ||||
| require 'rails_helper' | ||||
| 
 | ||||
| # Specs in this file have access to a helper object that includes | ||||
| # the HomeworkBanksHelper. For example: | ||||
| # | ||||
| # describe HomeworkBanksHelper do | ||||
| #   describe "string concat" do | ||||
| #     it "concats two strings with spaces" do | ||||
| #       expect(helper.concat_strings("this","that")).to eq("this that") | ||||
| #     end | ||||
| #   end | ||||
| # end | ||||
| RSpec.describe HomeworkBanksHelper, type: :helper do | ||||
|   pending "add some examples to (or delete) #{__FILE__}" | ||||
| end | ||||
					Loading…
					
					
				
		Reference in new issue