Merge branch 'dev_aliyun' of http://bdgit.educoder.net/Hjqreturn/educoder into dev_aliyun

issues25489
cxt 5 years ago
commit e5c6258883

@ -290,6 +290,7 @@ class GamesController < ApplicationController
answer_deduction = challenge.challenge_answers.where("level <= #{@answer.level}").sum(:score)
@game.update_attributes!(:answer_open => answer_open, :answer_deduction => answer_deduction)
end
GameAnswer.create!(challenge_answer_id: @answer.id, user_id: current_user.id, game_id: @game.id, view_time: Time.now)
rescue Exception => e
uid_logger_error("#######金币扣除异常: #{e.message}")
@ -317,6 +318,7 @@ class GamesController < ApplicationController
@game.update_attributes!(:answer_open => 1, :answer_deduction => 100)
end
@challenge_chooses = @challenge.challenge_chooses
GameAnswer.create!(user_id: current_user.id, game_id: @game.id, view_time: Time.now)
rescue Exception => e
uid_logger_error("#######金币扣除异常: #{e.message}")
raise ActiveRecord::Rollback

@ -11,4 +11,8 @@ module MyshixunsHelper
nil
end
end
def view_answer_time game, user_id
game.game_answers.where(user_id: user_id).last&.view_time
end
end

@ -1,4 +1,9 @@
class ChallengeAnswer < ApplicationRecord
default_scope { order("challenge_answers.level asc") }
belongs_to :challenge
has_many :game_answers, :dependent => :destroy
def view_answer_time(user_id)
game_answers.where(user_id: user_id).last&.view_time
end
end

@ -15,7 +15,7 @@ class Game < ApplicationRecord
belongs_to :user
belongs_to :challenge
has_one :run_code_message, :dependent => :destroy
has_many :game_answers, :dependent => :destroy
#全部关卡数
scope :ch_games, lambda { |challenge_id| where(challenge_id:challenge_id) }

@ -0,0 +1,5 @@
class GameAnswer < ApplicationRecord
belongs_to :user
belongs_to :game
belongs_to :challenge_answer
end

@ -249,6 +249,7 @@
autoRefresh: true,
smartIndent: true,//智能换行
styleActiveLine: true,
lineWrapping: true,
lint: true,
readOnly: "nocursor"
});

@ -16,7 +16,7 @@
<td class="action-container">
<% if prize_user.leader? && prize_user.competition_prize.category == 'bonus' %>
<% bank_content = [prize_user.extra&.[]('bank'), prize_user.extra&.[]('second_bank'), prize_user.extra&.[]('card_no')].compact.join('<br>').presence || '无' %>
<%= javascript_void_link('查看银行账户', data: { toggle: 'popover', title: '银行账号', content: bank_content.html_safe, html: true }) %>
<%= javascript_void_link('查看银行账户', data: { toggle: 'tooltip', title: bank_content.html_safe, html: true, placement: 'left', trigger: 'click' }) %>
<% end %>
<% if prize_user.pending? %>

@ -5,6 +5,7 @@ if @leader
json.bank_account_editable @bank_account_editable
end
json.all_certified current_user.all_certified?
json.personal_certifications do
json.array! @self_prizes do |prize_user|
json.url personal_competition_certificate_path(current_competition.identifier, prize_user)

@ -7,6 +7,7 @@ json.message do
json.answer_id answer.id
json.answer_name answer.name
json.answer_score answer.score
json.view_time answer.view_answer_time(current_user.id)
# 高层级不给答案
if @power || @game.answer_open >= index
json.answer_contents answer.contents

@ -6,4 +6,6 @@ json.array! @games do |game|
json.identifier get_game_identifier(@shixun.task_pass, game, @identity)
json.get_gold game.user_get_gold_and_experience(@shixun.status, challenge)[0]
json.get_experience game.user_get_gold_and_experience(@shixun.status, challenge)[1]
json.view_answer_time view_answer_time(game, current_user.id)
json.finished_time game.end_time
end

@ -0,0 +1,13 @@
class CreateGameAnswers < ActiveRecord::Migration[5.2]
def change
create_table :game_answers do |t|
t.references :challenge_answer
t.references :user
t.references :game
t.datetime :view_time
t.timestamps
end
end
end

@ -0,0 +1,5 @@
class AddIndexForGameAnswers < ActiveRecord::Migration[5.2]
def change
add_index :game_answers, [:challenge_answer_id, :user_id], :unique => true
end
end

@ -10,8 +10,9 @@
out+=this.renderer.em(this.output(cap[2]||cap[1])) -->
out+=this.renderer.em(this.output(cap[2]||cap[1]), cap.input)
*/
// 0.4.0 /^ *(#{1,6}) ——》/^ *(#{1,6}) 去掉了一个空格 TODO 行内公式带_
// 0.4.0 /^ *(#{1,6}) ——》/^ *(#{1,6}) 去掉了一个空格
/*if("string"!=typeof e)throw new Error("marked(): input parameter is of type "+Object.prototype.toString.call(e)+", string expected");*/
// 说明:左边 --> 右边 左边被替换成了右边的内容
// b(i[1].replace(/^ *| *\| *$/g,"")) --> i[1].replace(/^ *| *\| *$/g, "").split(/ *\| */) table没识别的问题
// header.length===a.align.length --> header.length table没识别的问题
// 2个table b(a.cells[p],a.header.length) -> a.cells[p].replace(/^ *\| *| *\| *$/g, "").split(/ *\| */)

@ -1 +1,17 @@
需要合并的js确保每个js的结尾都有个;号,不然合并后会报脚本错误。
js_min_all含的js
es6-shim
jQuery v1.8.3
Underscore.js 1.8.2
marked v0.3.3
Raphaël 2.1.3
js sequence diagrams 1.0.4
flowchart, v1.3.4
jQuery.flowchart.js v1.1.0
https://github.com/pandao/editor.md
http://codemirror.net
diff_match_patch
codemirror merge.js
从 edu_tpi.js 挪过来的js

@ -140,7 +140,10 @@ class CompetitionContentspdfdownload extends Component{
</Row>
<Row className={"mt30"}>
<Col>个人证书{data&&data.personal_certifications.length===0?<span><span className={"pdfpicture font-14"}>暂未生成</span> <span className={"ml20"}><span className={"pdfpicture font-14"}></span><a className={"pdfdownloadfont4CACFF"} onClick={()=>this.props.Competitioncallback("2")}></a></span></span>:
<Col>个人证书{data&&data.personal_certifications.length===0&&data&&data.all_certified===false?
<span><span className={"pdfpicture font-14"}>暂未生成</span> <span className={"ml20"}><span className={"pdfpicture font-14"}></span><a className={"pdfdownloadfont4CACFF"} onClick={()=>this.props.Competitioncallback("2")}></a></span></span>:
data&&data.personal_certifications.length===0&&data&&data.all_certified===true?
<span><span className={"pdfpicture font-14"}>暂未生成</span> <span className={"ml20"}><span className={"pdfpicture font-14"}></span></span></span>:
data&&data.personal_certifications.map((item,key)=>{
return(
<span className={"mr10"} key={key}>

@ -160,7 +160,18 @@ class Statistics extends Component{
derivefun=(url)=>{
let{group_ids}=this.state;
this.props.slowDownload(`${url}?group_id=${group_ids}`);
let list=group_ids;
let urllist="";
if(list!=undefined&&list.length!=0)
list.map((item,key)=>{
if(key===0){
urllist=`group_id[]=${item}`
}else{
urllist=urllist+`&group_id[]=${item}`
}
})
this.props.slowDownload(`${url}?${urllist}`);
}

@ -20,3 +20,38 @@ TPIContextProvider
代码内容通过以下接口获取:
`/tasks/${game.identifier}/rep_content.json?path=${path}&status=${status}&retry=${isRetry ? 1 : 0}`
层次结构
TPIContextProvider
page/Index
Header
TaskListContainer
TaskList 左侧划出的任务列表
MainContentContainer
MainContent
LeftViewContainer 左侧区域
LeftView
ChooseAnswerView 选择题答案
CommentContainer
Comments 评论列表
CodeEvaluateMultiLevelAnswerUnlock 多级别解锁
// 看设置是vnc or 代码 or 选择题
CodeRepositoryViewContainer for VNC
VNCContainer
CodeEvaluateView 代码评测结果
VNCDisplay vnc显示
ActionView 评测按钮区
|| CodeRepositoryViewContainer 代码显示区
WebSSHTimer ssh倒计时
TPIMonaco monaco编辑器
|| ChooseRepositoryView 选择题显示区
// 看设置,是代码 or 选择题
CodeEvaluateView
|| ChooseEvaluateView
ActionView 评测按钮区
没用的文件
LeftNav.js
AnswerListContainer.js left 他人解答

@ -132,6 +132,7 @@ function create_editorMD(id, width, high, placeholder, imageUrl, callback, initV
// Or return editormd.toolbarModes[name]; // full, simple, mini
// Using "||" set icons align right.
const icons = ["bold", "italic", "|", "list-ul", "list-ol", "|", "code", "code-block", "link", "|", "testIcon", "testIcon1", '|', "image", "table", '|', "watch", "clear"];
// 试卷处用到的填空题新增按钮
if (__that.props.showNullButton) {
icons.push('nullBtton')
}
@ -228,12 +229,14 @@ export default class TPMMDEditor extends Component {
const imageUrl = `/api/attachments.json`;
// 创建editorMd
let react_id = `react_${_id}`;
// 将实例存到了window
window[react_id] = this
const answers_editormd = create_editorMD(_id, '100%', this.props.height, _placeholder, imageUrl, (_editorName) => {
const __editorName = _editorName;
react_id = `react_${__editorName.id}`;
const that = window[react_id]
// 一个延迟的recreate或resize不加这段代码md初始化可能会出现样式问题
setTimeout(() => {
if (that.props.needRecreate == true) {
__editorName.recreate() // 注意 必须在setValue之前触发不然会清空
@ -268,6 +271,7 @@ export default class TPMMDEditor extends Component {
that.props.onCMBeforeChange(cm,change)
})
that.answers_editormd = __editorName;
// 这里应该可以去掉了,方便调试加的
window[__editorName.id+'_'] = __editorName;
}, initValue, this.onEditorChange,this.props.watch, {
noStorage: this.props.noStorage,
@ -276,6 +280,7 @@ export default class TPMMDEditor extends Component {
}, this);
}
// 用在form里时validate失败时出现一个红色边框
showError = () => {
this.setState({showError: true})
}

@ -28,6 +28,8 @@ const Option = Select.Option;
const RadioGroup = Radio.Group;
const { TextArea } = Input;
function create_editorMD(id, width, high, placeholder, imageUrl, callback) {
var editorName = window.editormd(id, {
width: width,
@ -1155,19 +1157,22 @@ export default class TPMevaluation extends Component {
</a>
</Tooltip>
</p>
<textarea className="textareavalue mb15" name="test_set[input][]"
<TextArea className="textareavalue mb15" name="test_set[input][]"
placeholder="输入"
value={item.input}
id={"textareavalue"+key}
autoHeight="true"
autoSize={{ minRows: 3, maxRows: 5 }}
onInput={(e)=>this.evaluationoninputvalue(e,key,"sr")}
></textarea>
<textarea className="textareavalue" name="test_set[output][]"
></TextArea>
<TextArea className="textareavalue" name="test_set[output][]"
placeholder="预期输出"
value={item.output}
id={key+"textareavalue"}
autoHeight="true"
autoSize={{ minRows: 3, maxRows: 5 }}
onInput={(e)=>this.evaluationoninputvalue(e,key,"yq")}
></textarea>
></TextArea>
<div className="clearfix lineh-30">
<span className="fl mr10 color-grey-6">匹配规则</span>
<RadioGroup className="fl" value={item.match_rule} onChange={(e)=>this.changeEvaluationRule(e,key)}>

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe GameAnswer, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end
Loading…
Cancel
Save