diff options
Diffstat (limited to 'toj')
26 files changed, 1685 insertions, 343 deletions
diff --git a/toj/index.html b/toj/index.html index 11a7a97..8f68a8b 100755 --- a/toj/index.html +++ b/toj/index.html @@ -6,8 +6,8 @@ <link href='http://fonts.googleapis.com/css?family=Droid+Sans' rel='stylesheet' type='text/css'> -<link rel="stylesheet" href="/codemirror.css"> -<link rel="stylesheet" href="/lesser-dark.css"> +<link rel="stylesheet" type="text/css" href="/codemirror.css"> +<link rel="stylesheet" type="text/css" href="/lesser-dark.css"> <link rel="stylesheet" type="text/css" href="/toj/jcs/common.css"> <link rel="stylesheet" type="text/css" href="/toj/jcs/index.css"> @@ -18,8 +18,9 @@ <link rel="stylesheet" type="text/css" href="/toj/jcs/sq.css"> <link rel="stylesheet" type="text/css" href="/toj/jcs/pro.css"> -<script src="/jquery-1.9.1.min.js"></script> -<script src="/jquery.easing.1.3.js"></script> +<script type="text/javascript" src="/jquery-1.9.1.min.js"></script> +<script type="text/javascript" src="/jquery.easing.1.3.js"></script> +<script type="text/javascript" src="https://www.google.com/jsapi"></script> <script type="text/javascript" src="/codemirror.js"></script> <script type="text/javascript" src="/clike.js"></script> <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script> @@ -87,13 +88,25 @@ a:hover{ color:#E9E9E9; text-decoration:underline; } -input,select{ +input{ + height:32px; font-size:16px; font-family:'Roboto','LiHei Pro','微軟正黑體'; + padding:0px 6px 0px 6px; + border-width:0px; + display:block; +} +select{ + height:32px; + font-size:16px; + font-family:'Roboto','LiHei Pro','微軟正黑體'; + border-width:0px; + display:block; } </style> <script type="text/javascript"> + google.load("visualization","1",{packages:["corechart"]}); $(document).ready(function(){ com.init(); user.init(); @@ -157,7 +170,7 @@ input,select{ <div class="com_pbox none_pbox"> <div style="margin:192px 0px 0px 246px;"> - <h1>Oops! 此頁不存在</h1> + <h1>Oops! 此頁不存在或權限不足</h1> <a href="/toj/home/" style="margin-left:6px; color:#E9E9E9;">回首頁</a> </div> </div> @@ -167,13 +180,17 @@ input,select{ <div class="subset"> <table class="filter"> <tr class="head"> - <th class="key"><h3>過濾器</h3></th> + <th class="key"><strong>過濾器</strong></th> <th class="value"><button class="clear">清除</button></th> </tr> <tr class="item uid"> <td class="key">UID</td> <td class="value">None</td> </tr> + <tr class="item proid"> + <td class="key">ProID</td> + <td class="value"><input type="textbox" value="None"></td> + </tr> <tr class="item result"> <td class="key">Result</td> <td class="value"> @@ -216,11 +233,29 @@ input,select{ </div> <div class="data_box"> <button class="looksub">查看動態</button> + <h2>統計</h2> + <div class="statis"> + <div class="subpie chart_box"> + <div class="title">上傳次數</div> + <div class="chart"></div> + </div> + <div class="trypie chart_box"> + <div class="title">嘗試題目</div> + <div class="chart"></div> + </div> + <div class="timecombo chart_box"> + <div class="title">時間</div> + <div class="chart"></div> + </div> + <div style="clear:both"></div> + </div> + <h2>已嘗試題目</h2> + <div class="trylist"></div> </div> </div> <div class="com_pbox edit_pbox"> <div class="edit_box"> - <h1>個人資料</h1> + <h2>個人資料</h2> <label>暱稱</label> <input name="nickname" type="textbox"> <label>照片</label> @@ -231,7 +266,7 @@ input,select{ <label>電子郵件</label> <input name="email" type="textbox"><br> - <h1>重設密碼</h1> + <h2>重設密碼</h2> <label>舊使用者密碼</label> <input name="password_old" type="password"> <label>新使用者密碼</label> @@ -246,29 +281,29 @@ input,select{ </div> <div class="com_pbox mgsq_pbox"> <div class="in_box"> - <h1>已加入方塊</h1> - <h2>等待中</h2> + <h2>已加入方塊</h2> + <h3>等待中</h3> <div class="wait"></div><br> - <h2>進行中</h2> + <h3>進行中</h3> <div class="run"></div><br> - <h2>已結束</h2> + <h3>已結束</h3> <div class="past"></div> </div> <div class="out_box"> - <h1>未加入方塊</h1> - <h2>等待中</h2> + <h2>未加入方塊</h2> + <h3>等待中</h3> <div class="wait"></div><br> - <h2>進行中</h2> + <h3>進行中</h3> <div class="run"></div><br> - <h2>已結束</h2> + <h3>已結束</h3> <div class="past"></div> </div> </div> <div class="com_pbox mg_pbox"> <div class="left_box"> - <h1>方塊</h1> + <h2>方塊</h2> <button class="newsq">建立方塊</button> - <h1>題目</h1> + <h2>題目</h2> <button class="newpro">建立題目</button> <table class="prolist"> <tr class="head"> @@ -325,7 +360,7 @@ input,select{ <div class="user_mask"> <div class="com_mbox editsq_mbox"> <div class="edit_box"> - <h1>基本資料</h1> + <h2>基本資料</h2> <label>方塊名稱</label> <input name="sqname" type="textbox" size="16" placeholder="foo"> <label>模組名稱</label> @@ -362,11 +397,11 @@ input,select{ <button class="delete" style="display:none;">刪除</button> </div> <div class="pro_box"> - <h1>已加入題目</h1> + <h2>已加入題目</h2> <div class="prolist_box"> <table class="prolist prolist_in"></table> </div> - <h1>未加入題目</h1> + <h2>未加入題目</h2> <div class="prolist_box"> <table class="prolist prolist_out"></table> </div> @@ -375,7 +410,7 @@ input,select{ </div> <div class="com_mbox editpro_mbox"> <div class="edit_box"> - <h1>基本資料</h1> + <h2>基本資料</h2> <label>題目名稱</label> <input name="name" type="textbox" size="16" placeholder="foo"> <label>模組ID</label> @@ -386,7 +421,7 @@ input,select{ <option value=2>隱藏</option> </select> <div class="update" style="display:none;"> - <h1>更新題目</h1> + <h2>更新題目</h2> <span class="cacheid"></span><br><br> <button class="update">更新</button> <button class="rejudge">重測</button> @@ -405,7 +440,7 @@ input,select{ <div class="title"></div> <div class="error"></div> <div class="oper"> - <select name="lang"> + <select name="lang" style="display:inline-block;"> <option value="1">C++</option> </select> <button class="submit">確定</button> diff --git a/toj/jcs/common.js b/toj/jcs/common.js index de5a707..6d4f0d3 100755 --- a/toj/jcs/common.js +++ b/toj/jcs/common.js @@ -1,4 +1,5 @@ var RESULTMAP = {0:'AC',1:'WA',2:'TLE',3:'MLE',4:'RF',5:'RE',6:'CE',7:'ERR',100:'WAIT'}; +var RESULTCOLOR = {0:'#00FF00',1:'#FF0000',2:'#FFFFFF',3:'#FFFFFF',4:'#FFFFFF',5:'#FFFFFF',6:'#FFFFFF',7:'#FFFFFF',100:'#FFFFFF'}; var USER_PER_USER = 0x00000001; var USER_PER_PROCREATOR = 0x00000002; @@ -90,7 +91,7 @@ var com = new function(){ that.url_curr = null; that.url_prev = null; that.url_back = null; - that.pbox_exist = false; + that.url_pbox = null; that.init = function(){ var i; @@ -155,23 +156,21 @@ var com = new function(){ window.history.replaceState(null,document.title,url); that.url_chg(); }; - that.url_pull = function(){ - that.url_update(that.url_back); + that.url_pull_pbox = function(){ + that.url_update(that.url_pbox); //window.history.back(); }; that.url_chg = function(){ var i; - var j; var ret; - var len; var stop_flag; var url_old; var url_new; var url_cpart; var url_ppart; - var is_mbox_prev; - var is_mbox_curr; + var is_mbox_old; + var is_mbox_new; var url_upart; var url_dpart; @@ -179,7 +178,50 @@ var com = new function(){ var node_parent; var node_bottom; + var _chg_out = function(url_ppart,url_cpart){ + var i; + var len; + + var url_upart; + var url_dpart; + var node_curr; + var node_parent; + var node_bottom; + + len = Math.min(url_ppart.length,url_cpart.length); + node_bottom = that.vus_root; + node_curr = node_bottom; + for(i = 0;i < len;i++){ + if(url_ppart[i] != url_cpart[i]){ + break; + } + if((node_curr = node_curr.child[url_ppart[i]]) == undefined){ + break; + } + node_bottom = node_curr; + } + if(node_curr != undefined){ + for(;i < url_ppart.length;i++){ + if(node_curr.child[url_ppart[i]] == undefined){ + break; + } + node_curr = node_curr.child[url_ppart[i]]; + } + + url_upart = url_ppart.slice(0); + url_dpart = new Array; + while(node_curr != node_bottom){ + node_parent = node_curr.parent; + node_curr.url_chg('out',url_upart,url_dpart); + url_dpart = url_dpart.splice(0,0,url_upart.pop()); + node_curr = node_parent; + } + } + + return node_bottom; + }; var _chg_in = function(url_cpart,idx,node_curr,url_upart,url_dpart){ + var node_parent; var delay_obj; for(;idx < url_cpart.length;idx++){ @@ -188,9 +230,9 @@ var com = new function(){ if((delay_obj = node_parent.delay_child[url_cpart[idx]]) == undefined){ that.url_update('/toj/none/'); }else{ - delay_obj.url_curr = that.url_curr; + delay_obj.url_curr = url_new; delay_obj.defer.done(function(){ - if(that.url_curr == delay_obj.url_curr){ + if(url_new == delay_obj.url_curr){ _chg_in(url_cpart,idx,node_parent,url_upart,url_dpart); } }); @@ -221,66 +263,44 @@ var com = new function(){ arguments.callee.hasnext = false; url_old = that.url_prev; - url_new = that.url_new; + url_new = that.url_curr; - url_cpart = that.url_curr.match(/toj\/(.*)/)[1].split('/'); + url_cpart = url_new.match(/toj\/(.*)/)[1].split('/'); url_cpart.pop(); if(url_cpart.length == 0){ that.url_update('/toj/home/'); continue; } - if(that.url_prev == null){ - is_mbox_prev = false; + if(url_old == null){ + is_mbox_old = false; }else{ - is_mbox_prev = check_mbox_url(that.url_prev); + is_mbox_old = check_mbox_url(url_old); } - is_mbox_curr = check_mbox_url(that.url_curr); + is_mbox_new = check_mbox_url(url_new); - stop_flag = false; - if(that.url_prev == null || (is_mbox_prev == false && is_mbox_curr == true)){ - i = 0; - node_curr = that.vus_root; - url_upart = new Array; - url_dpart = url_cpart.slice(0); + if(url_old == null || (is_mbox_old == false && is_mbox_new == true)){ + node_bottom = that.vus_root; + }else if(that.url_pbox != null && is_mbox_old == true && is_mbox_new == false){ + url_ppart = that.url_pbox.match(/toj\/(.*)/)[1].split('/'); + url_ppart.pop(); + node_bottom = _chg_out(url_ppart,url_cpart); }else{ - url_ppart = that.url_prev.match(/toj\/(.*)/)[1].split('/'); + url_ppart = url_old.match(/toj\/(.*)/)[1].split('/'); url_ppart.pop(); - - len = Math.min(url_ppart.length,url_cpart.length); - node_bottom = that.vus_root; - node_curr = node_bottom; - for(i = 0;i < len;i++){ - if(url_ppart[i] != url_cpart[i]){ - break; - } - if((node_curr = node_curr.child[url_ppart[i]]) == undefined){ - break; - } - node_bottom = node_curr; - } - if(node_curr != undefined){ - for(;i < url_ppart.length;i++){ - if(node_curr.child[url_ppart[i]] == undefined){ - break; - } - node_curr = node_curr.child[url_ppart[i]]; - } + node_bottom = _chg_out(url_ppart,url_cpart); + } - url_upart = url_ppart.slice(0); - url_dpart = new Array; - while(node_curr != node_bottom){ - node_parent = node_curr.parent; - node_curr.url_chg('out',url_upart,url_dpart); - url_dpart = url_dpart.splice(0,0,url_upart.pop()); - node_curr = node_parent; - } - } + if(url_old != null && is_mbox_old == false && is_mbox_new == false){ + index.page_scroll_reset(); + } + if(url_new != that.url_pbox){ i = 0; node_curr = that.vus_root; url_upart = new Array; url_dpart = url_cpart.slice(0); + stop_flag = false; while(node_curr != node_bottom){ if((node_curr = node_curr.child[url_cpart[i]]) == undefined){ break; @@ -293,19 +313,23 @@ var com = new function(){ } i++; } + if(stop_flag == false){ + _chg_in(url_cpart,i,node_curr,url_upart,url_dpart); + } } - if(that.url_prev != null && is_mbox_prev == false && is_mbox_curr == false){ - index.page_scroll_reset(); - } - if(stop_flag == false && (that.url_prev == null || that.pbox_exist == false || !(is_mbox_prev == true && is_mbox_curr == false))){ - _chg_in(url_cpart,i,node_curr,url_upart,url_dpart); + if(that.url_pbox != null && is_mbox_old == true && is_mbox_new == false){ + url_ppart = url_old.match(/toj\/(.*)/)[1].split('/'); + url_ppart.pop(); + _chg_out(url_ppart,url_cpart); } - if(that.pbox_exist == false && is_mbox_curr == false){ - that.pbox_exist = true; - $('#index_mask').removeClass('index_mask_nopbox'); - $('#index_mask').addClass('index_mask'); + if(is_mbox_new == false){ + if(that.url_pbox == null){ + $('#index_mask').removeClass('index_mask_nopbox'); + $('#index_mask').addClass('index_mask'); + } + that.url_pbox = url_new; } } @@ -393,6 +417,45 @@ var com = new function(){ return date.getFullYear() + '-' + month + '-' + day + ' ' + hr + ':' + min; } }; + that.get_durstring = function(duration,secflag){ + var sec; + var min; + var hr; + var day; + + duration = Math.floor(duration / 1000); + + sec = duration % 60; + duration = Math.floor(duration / 60); + if(sec < 10){ + sec = '0' + sec; + } + + min = duration % 60; + duration = Math.floor(duration / 60); + if(min < 10){ + min = '0' + min; + } + + hr = duration % 24; + duration = Math.floor(duration / 24); + if(hr < 10){ + hr = '0' + hr; + } + + day = duration; + if(day == 0){ + day = ''; + }else{ + day = day + ':'; + } + + if(secflag == true){ + return day + hr + ':' + min + ':' + sec; + }else{ + return day + hr + ':' + min; + } + }; that.get_lang = function(value){ var i; var ret; diff --git a/toj/jcs/index.js b/toj/jcs/index.js index 102d067..1d90756 100755 --- a/toj/jcs/index.js +++ b/toj/jcs/index.js @@ -62,11 +62,11 @@ var index = new function(){ $('#index_mask').on('click',function(e){ if((e.target == this || e.target.parentNode == this) && $(this).hasClass('index_mask')){ - com.url_pull(); + com.url_pull_pbox(); } }); $('#index_mask > button.close').on('click',function(e){ - com.url_pull(); + com.url_pull_pbox(); }); }; diff --git a/toj/jcs/pro.js b/toj/jcs/pro.js index ee28217..b2ea9ba 100755 --- a/toj/jcs/pro.js +++ b/toj/jcs/pro.js @@ -151,7 +151,7 @@ var class_pro_sub_mbox = function(){ j_error.text('其他錯誤'); } }else{ - com.url_pull(); + com.url_pull_pbox(); } }); }); diff --git a/toj/jcs/stat.css b/toj/jcs/stat.css index 3293a98..88a465c 100755 --- a/toj/jcs/stat.css +++ b/toj/jcs/stat.css @@ -12,7 +12,7 @@ div.stat_page > div.sub_pbox > div.subset > table.filter tr.head{ height:64px; } div.stat_page > div.sub_pbox > div.subset > table.filter tr.item{ - height:32px; + height:38px; } div.stat_page > div.sub_pbox > div.subset > table.filter th.key,div.stat_page > div.sub_pbox > div.subset > table.filter td.key{ width:76px; diff --git a/toj/jcs/stat.js b/toj/jcs/stat.js index 046c27f..95ec06a 100755 --- a/toj/jcs/stat.js +++ b/toj/jcs/stat.js @@ -110,13 +110,14 @@ var stat = new function(){ $.post('/toj/php/status.php',{'action':'get_by_subid','data':JSON.stringify({'subid':that.sub_subid})},function(res){ var reto; - if(res[0] != 'E'){ + if(res[0] == 'E'){ + com.url_update('/toj/none/'); + }else{ reto = JSON.parse(res); subid_node.smodname = reto.smodname; reto.submit_time = com.get_date(reto.submit_time); delete reto.smodname; - css = $('<link rel="stylesheet" type="text/css" href="/toj/smod/' + subid_node.smodname + '/' + subid_node.smodname + '.css">'); $('head').append(css); css.ready(function(){ @@ -143,7 +144,7 @@ var stat = new function(){ j_button = $('<button style="margin:6px 0px 0px 6px; float:right;">重測</button>'); j_button.on('click',function(e){ $.post('/toj/php/status.php',{'action':'rejudge_submit','data':JSON.stringify({'subid':that.sub_subid})}); - com.url_pull(); + com.url_pull_pbox(); }); j_subres_mbox.prepend(j_button); } @@ -155,8 +156,6 @@ var stat = new function(){ }); }); }); - }else{ - com.url_update('/toj/none/'); } }); } @@ -233,7 +232,7 @@ var class_stat_sub_pbox = function(pbox_name){ } j_ajax = $.post('/toj/php/status.php',{'action':'get_submit', 'data':JSON.stringify({ - 'filter':{'uid':filter.uid,'result':filter.result,'proid':null,'lang':null}, + 'filter':{'uid':filter.uid,'result':filter.result,'proid':filter.proid,'lang':null}, 'sort':{'score':null,'runtime':null,'memory':null,'subid':[1,0]}, 'wait':10, 'count':100, @@ -292,7 +291,7 @@ var class_stat_sub_pbox = function(pbox_name){ down_block = true; $.post('/toj/php/status.php',{'action':'get_submit', 'data':JSON.stringify({ - 'filter':{'uid':filter.uid,'result':filter.result,'proid':null,'lang':null}, + 'filter':{'uid':filter.uid,'result':filter.result,'proid':filter.proid,'lang':null}, 'sort':{'score':null,'runtime':null,'memory':null,'subid':[0,esubid]}, 'wait':0, 'count':50, @@ -363,11 +362,15 @@ var class_stat_sub_pbox = function(pbox_name){ ret = ''; if(filter.uid != null){ - ret += 'uid:' + filter.uid; + ret += 'uid:' + filter.uid + ':'; + } + if(filter.proid != null){ + ret += 'proid:' + filter.proid + ':'; } if(filter.result != null){ - ret += 'result:' + filter.result; + ret += 'result:' + filter.result + ':'; } + ret = ret.slice(0,-1); return ret; }; @@ -379,11 +382,14 @@ var class_stat_sub_pbox = function(pbox_name){ that.node.url_chg = function(direct,url_upart,url_dpart){ var i; var filter_part; + var key; + var value; var _clear = function(){ $(window).off('scorll'); j_filter.find('tr.uid > td.value').text('None'); - j_filter.find('tr.result select').val(null); + j_filter.find('tr.proid input').val('None'); + j_filter.find('tr.result select').val('null'); j_table.find('tr.item').remove(); if(j_ajax != null){ @@ -413,14 +419,20 @@ var class_stat_sub_pbox = function(pbox_name){ refresh_flag = true; filter.uid = null; + filter.proid = null; filter.result = null; if(url_dpart[0] != undefined){ filter_part = url_dpart[0].split(':'); for(i = 0;i < filter_part.length;i += 2){ - if(filter_part[i] == 'uid'){ - filter.uid = parseInt(filter_part[i + 1]); - }else if(filter_part[i] == 'result'){ - filter.result = parseInt(filter_part[i + 1]); + key = filter_part[i]; + value = filter_part[i + 1]; + + if(key == 'uid'){ + filter.uid = parseInt(value); + }else if(key == 'proid'){ + filter.proid = parseInt(value); + }else if(key == 'result'){ + filter.result = parseInt(value); } } } @@ -428,6 +440,9 @@ var class_stat_sub_pbox = function(pbox_name){ if(filter.uid != null){ j_filter.find('tr.uid > td.value').text(filter.uid); } + if(filter.proid != null){ + j_filter.find('tr.proid input').val(filter.proid); + } if(filter.result != null){ j_filter.find('tr.result select').val(filter.result); } @@ -442,6 +457,31 @@ var class_stat_sub_pbox = function(pbox_name){ return 'stop'; }; + j_pbox.find('div.subset > table.filter tr.proid input').on('focusin',function(e){ + if($(this).val() == 'None'){ + $(this).val(''); + } + }).on('focusout',function(e){ + if($(this).val() == ''){ + $(this).val('None'); + } + }).on('keypress',function(e){ + var param; + + if(e.which != 13){ + return; + } + + if((filter.proid = $(this).val()) == 'None'){ + filter.proid = null; + } + console.log(filter.proid); + if((param = filter_getparam()) != ''){ + com.url_push('/toj/stat/sub/' + param + '/'); + }else{ + com.url_push('/toj/stat/sub/'); + } + }); j_pbox.find('div.subset > table.filter tr.result select').on('change',function(e){ var param; diff --git a/toj/jcs/user.css b/toj/jcs/user.css index 37dd3f7..a99f8c9 100755 --- a/toj/jcs/user.css +++ b/toj/jcs/user.css @@ -26,6 +26,44 @@ div.user_page > div.main_pbox > div.data_box{ padding:32px 0px 32px 0px; float:left; } +div.user_page > div.main_pbox > div.data_box > div.statis > div.chart_box{ + width:322px; + height:240px; + margin:0px 6px 6px 0px; + background-color:#1C1C1C; + float:left; + position:relative; +} +div.user_page > div.main_pbox > div.data_box > div.statis > div.chart_box > div.title{ + position:absolute; + top:6px; + left:6px; + z-index:1 +} +div.user_page > div.main_pbox > div.data_box > div.statis > div.chart_box > div.chart{ + width:100%; + height:100%; + position:absolute; + top:0px; + left:0px; + z-index:0 +} +div.user_page > div.main_pbox > div.data_box > div.statis > div.timecombo{ + width:978px; + height:240px; +} +div.user_page > div.main_pbox > div.data_box > div.trylist > span.item{ + width:35px; + height:24px; + margin:0px 6px 6px 0px; + line-height:24px; + background-color:#1C1C1C; + display:inline-block; +} +div.user_page > div.main_pbox > div.data_box > div.trylist > span.item > a{ + padding:0px 0px 0px 3px; + font-size:12px; +} div.user_page > div.edit_pbox > div.edit_box{ width:240px; margin:0px 0px 0px 246px; @@ -42,11 +80,7 @@ div.user_page > div.edit_pbox > div.edit_box > div.error{ } div.user_page > div.edit_pbox > div.edit_box input{ width:228px; - height:32px; margin:0px 0px 16px 0px; - padding:0px 6px 0px 6px; - border-width:0px; - display:block; } div.user_page > div.mgsq_pbox > div.in_box{ width:486px; @@ -130,11 +164,7 @@ div.user_mask > div.editsq_mbox > div.edit_box > div.error{ } div.user_mask > div.editsq_mbox > div.edit_box input{ width:146px; - height:32px; margin:0px 0px 16px 0px; - padding:0px 6px 0px 6px; - border-width:0px; - display:block; } div.user_mask > div.editsq_mbox > div.edit_box > div.time > input{ width:35px; @@ -143,8 +173,6 @@ div.user_mask > div.editsq_mbox > div.edit_box select{ width:76px; height:32px; margin:0px 0px 16px 0px; - border-width:0px; - display:block; } div.user_mask > div.editsq_mbox > div.pro_box{ width:404px; @@ -188,9 +216,6 @@ div.user_mask > div.editpro_mbox > div.edit_box input{ width:146px; height:32px; margin:0px 0px 16px 0px; - padding:0px 6px 0px 6px; - border-width:0px; - display:block; } div.user_mask > div.editpro_mbox > div.edit_box select{ width:76px; @@ -219,9 +244,6 @@ div.login_pbox > div.login_box > input{ width:228px; height:32px; margin:0px 0px 16px 0px; - padding:0px 6px 0px 6px; - border-width:0px; - display:block; } div.register_pbox > div.info_box{ @@ -243,7 +265,4 @@ div.register_pbox > div.register_box > input{ width:228px; height:32px; margin:0px 0px 16px 0px; - padding:0px 6px 0px 6px; - border-width:0px; - display:block; } diff --git a/toj/jcs/user.js b/toj/jcs/user.js index 1a45a32..4aa7252 100755 --- a/toj/jcs/user.js +++ b/toj/jcs/user.js @@ -181,7 +181,7 @@ var user = new function(){ 'data':{'action':'view','data':JSON.stringify({'uid':null})}, 'async':!sync, 'success':function(res){ - var reto; + var usero; var old_uid; old_uid = that.uid; @@ -197,14 +197,14 @@ var user = new function(){ that.login_chg.fire(false); }else{ - reto = JSON.parse(res); - that.uid = reto.uid; - that.level = reto.level; - that.username = reto.username; - that.nickname = reto.nickname; - that.avatar = reto.avatar; - that.aboutme = reto.aboutme; - that.email = reto.email; + usero = JSON.parse(res).user; + that.uid = usero.uid; + that.level = usero.level; + that.username = usero.username; + that.nickname = usero.nickname; + that.avatar = usero.avatar; + that.aboutme = usero.aboutme; + that.email = usero.email; if(old_uid != that.uid){ that.login_chg.fire(true); @@ -264,20 +264,158 @@ var class_user_main_pbox = function(){ that.fadein(j_pbox); $.post('/toj/php/user.php',{'action':'view','data':JSON.stringify({'uid':user.view_uid})},function(res){ + var i; + var reto; + var usero; + var statiso; + var trylist; + var substatis; + var actry; + var series; + var total; + + var j_div; + var j_span; + var j_a; + + var pie_add = function(j_div,series){ + var draw = function(){ + var data = google.visualization.arrayToDataTable(series); + var chart = new google.visualization.PieChart(j_div[0]); + + chart.draw(data,{ + 'chartArea':{'width':'90%','height':'85%','top':'15%','left':'10%'}, + 'backgroundColor':'#1C1C1C', + 'legend':{ + 'textStyle':{'color':'#E9E9E9'} + }, + 'pieSliceBorderColor':'#E9E9E9', + 'pieSliceText':'value', + 'titleTextStyle':{'color':'#E9E9E9','fontSize':'16'} + }); + } + if(typeof google === 'object'){ + draw(); + }else{ + google.setOnLoadCallback(draw); + } + }; + var combo_add = function(j_div,series){ + var draw = function(){ + var data = google.visualization.arrayToDataTable(series); + var chart = new google.visualization.ComboChart(j_div[0]); + + chart.draw(data,{ + 'backgroundColor':'#1C1C1C', + 'legend':{ + 'textStyle':{'color':'#E9E9E9'} + }, + 'titleTextStyle':{'color':'#E9E9E9','fontSize':'16'}, + 'hAxis':{'textStyle':{'color':'#E9E9E9'},'slantedText':false}, + 'vAxis':{'textStyle':{'color':'#E9E9E9'}}, + 'series':{'0':{'type':'bars','targetAxisIndex':0}} + }); + } + if(typeof google === 'object'){ + draw(); + }else{ + google.setOnLoadCallback(draw); + } + }; + var draw_timeline = function(timesub){ + var i; + var j; + var series; + var part; + var last_time; + var curr_time; + + if(timesub.length == 0){ + return; + } + series = new Array(); + series.push(['Time','上傳次數']); + + part = timesub[0].time.split('-'); + last_time = parseInt(part[0]) * 12 + parseInt(part[1]) + 1; + + series.push([timesub[0].time,timesub[0].count]); + + for(i = 1;i < timesub.length;i++){ + part = timesub[i].time.split('-'); + curr_time = parseInt(part[0]) * 12 + parseInt(part[1]); + + for(;last_time < curr_time;last_time++){ + if((last_time % 6) == 1){ + series.push([Math.floor(last_time / 12) + '-' + last_time % 12,0]); + }else{ + series.push(['',0]); + } + } + + if((last_time % 6) == 1){ + series.push([Math.floor(last_time / 12) + '-' + last_time % 12,timesub[i].count]); + }else{ + series.push(['',timesub[i].count]); + } + + last_time = curr_time + 1; + } + + combo_add(j_pbox.find('div.data_box > div.statis > div.timecombo > div.chart'),series); + }; if(res[0] == 'E'){ com.url_update('/toj/none/'); }else{ reto = JSON.parse(res); - j_pbox.find('div.info_box > div.name').text(reto.nickname + ' (' + reto.username + ')'); - if(reto.avatar == ''){ + usero = reto.user; + statiso = reto.statis; + + j_pbox.find('div.info_box > div.name').text(usero.nickname + ' (' + usero.username + ')'); + if(usero.avatar == ''){ j_pbox.find('div.info_box > img.avatar').attr('src','http://i.imgur.com/ykkQD.png'); }else{ - j_pbox.find('div.info_box > img.avatar').attr('src',reto.avatar); + j_pbox.find('div.info_box > img.avatar').attr('src',usero.avatar); + } + j_pbox.find('div.info_box > div.aboutme').text(usero.aboutme); + + j_div = j_pbox.find('div.data_box > div.trylist'); + trylist = statiso.trylist; + actry = 0; + for(i = 0;i < trylist.length;i++){ + j_span = $('<span class="item"><a></a></span>'); + + j_a = j_span.find('a'); + j_a.css('color',RESULTCOLOR[trylist[i].result]); + j_a.text(trylist[i].proid); + j_a.attr('href','/toj/pro/' + trylist[i].proid + '/'); + + j_div.append(j_span); + + if(trylist[i].result == 0){ + actry++; + } } - j_pbox.find('div.info_box > div.aboutme').text(reto.aboutme); + substatis = statiso.substatis; + series = new Array(); + series[0] = ['Result','Count']; + total = 0; + for(i = 0;i < substatis.length;i++){ + series[i + 1] = [RESULTMAP[substatis[i].result],substatis[i].count]; + } + + pie_add(j_pbox.find('div.data_box > div.statis > div.subpie > div.chart'),series); + + pie_add(j_pbox.find('div.data_box > div.statis > div.trypie > div.chart'), + [['Result','Count'], + ['AC',actry], + ['Failed',statiso.trylist.length - actry] + ]); + + draw_timeline(statiso.timesub); } }); }else if(direct == 'out'){ @@ -286,6 +424,7 @@ var class_user_main_pbox = function(){ j_pbox.find('div.info_box > div.name').text(''); j_pbox.find('div.info_box > img.avatar').attr('src',''); + j_pbox.find('div.data_box > div.trylist').empty(); } }; @@ -849,18 +988,19 @@ var class_user_editsq_mbox = function(){ j++; pro_listset(j_item,proo,type); - j_last = j_item; }else{ j_item = pro_listnew(proo,type); j_item.hide(); if(j_last == null){ - j_table.append(j_item); + j_table.prepend(j_item); }else{ j_item.insertAfter(j_last); } j_item.css('opacity',0).slideDown('fast').fadeTo(100,1); } + + j_last = j_item; } for(;j < trs.length;j++){ j_item = $(trs[j]); @@ -930,6 +1070,8 @@ var class_user_editsq_mbox = function(){ j_mbox.find('[name="e_min"]').val(sqo.end_time.getMinutes()); } j_mbox.find('button.delete').show(); + + pro_update(); } com.vus_mbox.child_set(that.node); @@ -940,7 +1082,6 @@ var class_user_editsq_mbox = function(){ that.node.url_chg = function(direct,url_upart,url_dpart){ if(direct == 'in'){ that.fadein(j_mbox); - pro_update(); }else if(direct == 'out'){ that.fadeout(j_mbox); @@ -992,7 +1133,7 @@ var class_user_editsq_mbox = function(){ } }else{ defer.resolve(); - com.url_pull(); + com.url_pull_pbox(); } }); } @@ -1049,7 +1190,7 @@ var class_user_editsq_mbox = function(){ } }else{ defer.resolve(); - com.url_pull(); + com.url_pull_pbox(); } }); }else if(action == 'edit'){ @@ -1074,13 +1215,13 @@ var class_user_editsq_mbox = function(){ }else{ user.update(false); defer.resolve(); - com.url_pull(); + com.url_pull_pbox(); } }); } }); j_mbox.find('button.cancel').on('click',function(e){ - com.url_pull(); + com.url_pull_pbox(); }); }; __extend(class_user_editsq_mbox,class_com_mbox); var class_user_editpro_mbox = function(){ @@ -1140,13 +1281,13 @@ var class_user_editpro_mbox = function(){ j_mbox.find('button.update').on('click',function(e){ $.post('/toj/php/problem.php',{'action':'update_pro_cache','data':JSON.stringify({'proid':proid})},function(res){ defer.resolve(); - com.url_pull(); + com.url_pull_pbox(); }); }); j_mbox.find('button.rejudge').on('click',function(e){ $.post('/toj/php/problem.php',{'action':'rejudge_pro','data':JSON.stringify({'proid':proid})},function(res){ defer.resolve(); - com.url_pull(); + com.url_pull_pbox(); }); }); j_mbox.find('button.submit').on('click',function(e){ @@ -1188,7 +1329,7 @@ var class_user_editpro_mbox = function(){ } }else{ defer.resolve(); - com.url_pull(); + com.url_pull_pbox(); } }); }else if(action == 'edit'){ @@ -1215,13 +1356,13 @@ var class_user_editpro_mbox = function(){ } }else{ defer.resolve(); - com.url_pull(); + com.url_pull_pbox(); } }); } }); j_mbox.find('button.cancel').on('click',function(e){ - com.url_pull(); + com.url_pull_pbox(); }); }; __extend(class_user_editpro_mbox,class_com_mbox); diff --git a/toj/php/common.inc.php b/toj/php/common.inc.php index 0922c91..18786e9 100755 --- a/toj/php/common.inc.php +++ b/toj/php/common.inc.php @@ -2,7 +2,10 @@ date_default_timezone_set('Asia/Taipei'); //error_reporting(E_ALL ^ E_NOTICE); +//ini_set("display_errors", "On"); + //error_reporting(0); +// require('connect.inc.php'); diff --git a/toj/php/sqlib_scoreboard.inc.php b/toj/php/sqlib_scoreboard.inc.php index e5e7d66..32bec44 100755 --- a/toj/php/sqlib_scoreboard.inc.php +++ b/toj/php/sqlib_scoreboard.inc.php @@ -71,14 +71,14 @@ sqlib_scoreboard::update($sqlc, $msqlc, $sqid, $sboard_id, $score_func, $start_time, $end_time); //display - $sqlstr = 'SELECT "a1"."uid", "a1"."rank_score", COUNT(*) AS "rank" FROM "sqlib_scoreboard_main" "a1", "sqlib_scoreboard_main" "a2" WHERE "a1"."sqid"=$1 AND "a1"."sboard_id"=$2 AND "a2"."sqid"=$1 AND "a2"."sboard_id"=$2 AND ("a2"."rank_score">"a1"."rank_score" OR "a2"."uid"="a1"."uid") GROUP BY "a1"."uid", "a1"."rank_score" ORDER BY "a1"."rank_score" DESC, "a1"."uid" LIMIT $4 OFFSET $3;'; - $sqlarr = array($sqid, $sboard_id, $start_offset-1, $number); + $sqlstr = 'SELECT "a1"."uid", "a1"."rank_score", COUNT(*) AS "rank" FROM "sqlib_scoreboard_main" "a1", "sqlib_scoreboard_main" "a2" WHERE "a1"."sqid"=$1 AND "a1"."sboard_id"=$2 AND "a2"."sqid"=$1 AND "a2"."sboard_id"=$2 AND ("a2"."rank_score">"a1"."rank_score" OR "a2"."uid"="a1"."uid") GROUP BY "a1"."uid", "a1"."rank_score" ORDER BY "a1"."rank_score" DESC, "a1"."uid" LIMIT $4 OFFSET $3;'; + $sqlarr = array($sqid, $sboard_id, $start_offset, $number); if($uid) { $sqlstr = 'SELECT "a1"."uid", "a1"."rank_score", COUNT(*) AS "rank" FROM "sqlib_scoreboard_main" "a1", "sqlib_scoreboard_main" "a2" WHERE "a1"."sqid"=$1 AND "a1"."sboard_id"=$2 AND "a1"."uid"=$3 AND "a2"."sqid"=$1 AND "a2"."sboard_id"=$2 AND ("a2"."rank_score">"a1"."rank_score" OR "a2"."uid"="a1"."uid") GROUP BY "a1"."uid", "a1"."rank_score";'; $sqlarr = array($sqid, $sboard_id, $uid); } - + $res = pg_query_params($msqlc, $sqlstr, $sqlarr); $arr = pg_fetch_all($res); diff --git a/toj/php/square.inc.php b/toj/php/square.inc.php index 4a4b52f..99f0d2e 100755 --- a/toj/php/square.inc.php +++ b/toj/php/square.inc.php @@ -226,6 +226,20 @@ class square } return $ret; } + public static function get_user_list($sqlc, $sqid) + { + //get problem list of square $sqid. + $sqlstr = 'SELECT "user"."uid", "user"."nickname" FROM "user" INNER JOIN "us_sq" ON "user"."uid"="us_sq"."uid" WHERE "us_sq"."sqid"=$1 ORDER BY "user"."uid";'; + $sqlarr = array($sqid); + $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr); + $ret = array(); + while($obj = pg_fetch_object($sqlr)) + { + $obj->uid = intval($obj->uid); + array_push($ret, $obj); + } + return $ret; + } } ?> diff --git a/toj/php/square.php b/toj/php/square.php index c95c584..fb87741 100755 --- a/toj/php/square.php +++ b/toj/php/square.php @@ -2,6 +2,7 @@ //ini_set("display_errors", "On"); require_once('square.inc.php'); +require_once('event.inc.php'); $sqlc = db_connect(); @@ -44,6 +45,9 @@ if($action == 'add_sq') if(!$res2) die('Eadd_admin_failed'); + if(event::exec_func('../sqmod/'.$sq->sqmodname.'/'.$sq->sqmodname.'.inc.php','event_create',[$res->sqid]) === false) + die('Eevent_error'); + echo('S'); } if($action == 'delete_sq') @@ -59,13 +63,17 @@ if($action == 'delete_sq') die('Epermission_denied'); $sqid = intval($sq->sqid); - if(!square::get($sqlc, $sqid)) - die('Eno_such_sq'); + $sq = square::get($sqlc, $sqid); + if(!$sq) + die('Ewrong_sqid'); $res = square::del($sqlc, $sqid); if(!$res) die('Edelete_failed'); + if(event::exec_func('../sqmod/'.$sq->sqmodname.'/'.$sq->sqmodname.'.inc.php','event_destroy',[$sq->sqid]) === false) + die('Eevent_error'); + echo('S'); } if($action == 'edit_sq') @@ -313,7 +321,8 @@ if($action == 'add_pro_into_sq') if(!problem::is_available($sqlc, $dt->proid)) die('Ewrong_proid'); - if(!square::get($sqlc, $dt->sqid)) + $sq = square::get($sqlc, $dt->sqid); + if(!$sq) die('Ewrong_sqid'); $adm = sec_check_level($sqlc, USER_LEVEL_SUPERADMIN) || square::get_user_relationship($sqlc, $uid, $dt->sqid) >= SQUARE_USER_ADMIN; @@ -328,6 +337,9 @@ if($action == 'add_pro_into_sq') if(!$ret) die('Eadd_problem_into_square_failed'); + if(event::exec_func('../sqmod/'.$sq->sqmodname.'/'.$sq->sqmodname.'.inc.php','event_add_pro',[$sq->sqid, $dt->proid]) === false) + die('Eevent_error'); + echo('S'); } if($action == 'delete_pro_from_sq') @@ -343,7 +355,8 @@ if($action == 'delete_pro_from_sq') $dt = json_decode($data); - if(!square::get($sqlc, $dt->sqid)) + $sq = square::get($sqlc, $dt->sqid); + if(!$sq) die('Ewrong_sqid'); $adm = sec_check_level($sqlc, USER_LEVEL_SUPERADMIN) || square::get_user_relationship($sqlc, $uid, $dt->sqid) >= SQUARE_USER_ADMIN; @@ -358,6 +371,9 @@ if($action == 'delete_pro_from_sq') if(!$ret) die('Edelete_problem_from_square_failed'); + if(event::exec_func('../sqmod/'.$sq->sqmodname.'/'.$sq->sqmodname.'.inc.php','event_del_pro',[$sq->sqid, $dt->proid]) === false) + die('Eevent_error'); + echo('S'); } diff --git a/toj/php/status.inc.php b/toj/php/status.inc.php index adc749f..f0ad3da 100755 --- a/toj/php/status.inc.php +++ b/toj/php/status.inc.php @@ -33,31 +33,31 @@ class status { $condstr = $condstr.'"submit"."uid"='.pg_escape_string($filter->uid).' AND '; } - if($filter->result != null) + if($filter->result !== null) { $condstr = $condstr.'"result"='.pg_escape_string($filter->result).' AND '; } if($filter->proid != null) { - $condstr = $condstr.'"proid"='.pg_escape_string($filter->proid).' AND '; + $condstr = $condstr.'"submit"."proid"='.pg_escape_string($filter->proid).' AND '; } if($filter->lang != null) { $condstr = $condstr.'"lang"='.pg_escape_string($filter->lang).' AND '; } - if($sort->score != null) + if($sort->score !== null) { $relstr = $sort->score[0]==0 ? '<=' : '>='; $condstr = $condstr.'"score"'.$relstr.pg_escape_string($sort->score[1]).' AND '; $ordstr = $ordstr.'"score" '.($sort->score[0]==0 ? 'DESC' : 'ASC').' ,'; } - if($sort->runtime != null) + if($sort->runtime !== null) { $relstr = $sort->runtime[0]==0 ? '<=' : '>='; $condstr = $condstr.'"runtime"'.$relstr.pg_escape_string($sort->runtime[1]).' AND '; $ordstr = $ordstr.'"runtime" '.($sort->runtime[0]==0 ? 'DESC' : 'ASC').' ,'; } - if($sort->maxmem != null) + if($sort->maxmem !== null) { $relstr = $sort->maxmem[0]==0 ? '<=' : '>='; $condstr = $condstr.'"memory"'.$relstr.pg_escape_string($sort->maxmem[1]).' AND '; diff --git a/toj/php/user.inc.php b/toj/php/user.inc.php index 8b3bb61..46205d7 100755 --- a/toj/php/user.inc.php +++ b/toj/php/user.inc.php @@ -192,6 +192,57 @@ class user return true; } + + public static function statistic($sqlc, $uid){ + $sqlstr = 'SELECT "proid",MIN("result") AS "result" FROM "submit" WHERE "uid"=$1 GROUP BY "proid" ORDER BY "proid" ASC;'; + $sqlarr = array(intval($uid)); + $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr); + $trylist = array(); + while($obj = pg_fetch_object($sqlr)){ + $obj->proid = intval($obj->proid); + $obj->result = intval($obj->result); + array_push($trylist, $obj); + } + pg_free_result($sqlr); + + $sqlstr = 'SELECT "result",COUNT("result") AS "count" FROM "submit" WHERE "uid"=$1 GROUP BY "result" ORDER BY "result";'; + $sqlarr = array(intval($uid)); + $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr); + $substatis = array(); + while($obj = pg_fetch_object($sqlr)){ + $obj->result = intval($obj->result); + $obj->count = intval($obj->count); + array_push($substatis, $obj); + } + pg_free_result($sqlr); + + $sqlstr = 'SELECT "result",COUNT("result") AS "count" FROM "submit" WHERE "uid"=$1 GROUP BY "result" ORDER BY "result";'; + $sqlarr = array(intval($uid)); + $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr); + $substatis = array(); + while($obj = pg_fetch_object($sqlr)){ + $obj->result = intval($obj->result); + $obj->count = intval($obj->count); + array_push($substatis, $obj); + } + pg_free_result($sqlr); + + $sqlstr = 'SELECT TO_CHAR("submit_time",\'YYYY-MM\') AS "time",COUNT("submit_time") AS "count" FROM "submit" WHERE uid=$1 GROUP BY TO_CHAR("submit_time",\'YYYY-MM\');'; + $sqlarr = array(intval($uid)); + $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr); + $timesub = array(); + while($obj = pg_fetch_object($sqlr)){ + $obj->count = intval($obj->count); + array_push($timesub, $obj); + } + pg_free_result($sqlr); + + return array( + 'trylist' => $trylist, + 'substatis' => $substatis, + 'timesub' => $timesub + ); + } } function sec_check_level($sqlc, $lv, $uid = null) diff --git a/toj/php/user.php b/toj/php/user.php index 4570700..23a15e6 100755 --- a/toj/php/user.php +++ b/toj/php/user.php @@ -125,7 +125,12 @@ if($action == 'view') if(intval($_COOKIE['uid']) != $user->uid) unset($user->email); - echo(json_encode($user)); + $statis = user::statistic($sqlc, $user->uid); + + echo(json_encode(array( + 'user' => $user, + 'statis' => $statis + ))); } if($action == 'login') { diff --git a/toj/sqmod/sqmod_contest/sqmod_contest.css b/toj/sqmod/sqmod_contest/sqmod_contest.css new file mode 100755 index 0000000..4932aae --- /dev/null +++ b/toj/sqmod/sqmod_contest/sqmod_contest.css @@ -0,0 +1,116 @@ +div.sqmod_contest > div.sboard_pbox > table.sboardlist{ + margin:32px 0px 6px 0px; + border-collapse:collapse; + text-align:left; +} +div.sqmod_contest > div.sboard_pbox > table.sboardlist tr.head{ + height:32px; +} +div.sqmod_contest > div.sboard_pbox > table.sboardlist tr.item{ + height:32px; + border-top:#BDC0BA 1px solid; +} +div.sqmod_contest > div.sboard_pbox > table.sboardlist th,div.sqmod_contest > div.sboard_pbox > table.sboardlist td{ + width:76px; + padding:0px 0px 0px 6px; + border-left:#BDC0BA 1px solid; +} +div.sqmod_contest > div.sboard_pbox > table.sboardlist th.rank,div.sqmod_contest > div.sboard_pbox > table.sboardlist td.rank{ + border-width:0px; +} +div.sqmod_contest > div.sboard_pbox > table.sboardlist th.nickname,div.sqmod_contest > div.sboard_pbox > table.sboardlist td.nickname{ + width:240px; +} +div.sqmod_contest > div.sboard_pbox > table.sboardlist th.pro,div.sqmod_contest > div.sboard_pbox > table.sboardlist td.pro{ + width:117px; + position:relative; +} +div.sqmod_contest > div.sboard_pbox > table.sboardlist td.pro > sup.try{ + color:#BDC0BA; +} +div.sqmod_contest > div.sboard_pbox > table.sboardlist td.pro > sub.time{ + color:#BDC0BA; +} + +div.sqmod_contest > div.pro_pbox > table.prolist{ + width:1060px; + margin:0px 0px 6px 164px; + border-collapse:collapse; + text-align:left; +} +div.sqmod_contest > div.pro_pbox > table.prolist tr.head{ + height:64px; +} +div.sqmod_contest > div.pro_pbox > table.prolist tr.item{ + height:32px; + border-left:2px solid; + border-color:#1C1C1C; +} +div.sqmod_contest > div.pro_pbox > table.prolist tr:hover.item{ + background-color:rgba(255,255,255,0.2); +} +div.sqmod_contest > div.pro_pbox > table.prolist th,div.sqmod_contest > div.pro_pbox > table.prolist td{ + width:76px; + padding:0px 0px 0px 6px; +} +div.sqmod_contest > div.pro_pbox > table.prolist th.name,div.sqmod_contest > div.pro_pbox > table.prolist td.name{ + width:auto; + padding:0px 0px 0px 0px; +} + +div.sqmod_contest > div.pro_pbox > table.stat{ + margin:32px 0px 6px 164px; + border-collapse:collapse; + text-align:left; +} +div.sqmod_contest > div.pro_pbox > table.stat tr{ + height:32px; +} +div.sqmod_contest > div.pro_pbox div.prog_box{ + width:486px; + height:16px; + background-color:rgba(255,255,255,0.2); + color:#1C1C1C; + font-size:12px; + font-family:monospace; + line-height:16px; + text-align:right; + position:relative; +} +div.sqmod_contest > div.pro_pbox div.prog_box > div.pass{ + width:0%; + height:16px; + border-right:rgba(0,255,0,0.8) 2px solid; + position:absolute; + top:0px; + left:0%; + overflow:hidden; +} +div.sqmod_contest > div.pro_pbox div.prog_box > div.good{ + width:0%; + height:16px; + border-right:rgba(255,255,0,0.8) 2px solid; + position:absolute; + top:0px; + left:0%; + overflow:hidden; +} +div.sqmod_contest > div.pro_pbox div.prog_box > div.total{ + width:0%; + height:16px; + border-right:rgba(255,255,255,0.8) 2px solid; + position:absolute; + top:0px; + left:0%; + overflow:hidden; +} +div.sqmod_contest > div.pro_pbox div.prog_box > div.prog{ + width:0%; + height:16px; + background-color:rgba(0,0,0,0); + font-weight:bold; + position:absolute; + top:0px; + left:0px; + overflow:hidden; +} diff --git a/toj/sqmod/sqmod_contest/sqmod_contest.html b/toj/sqmod/sqmod_contest/sqmod_contest.html new file mode 100755 index 0000000..3f7c759 --- /dev/null +++ b/toj/sqmod/sqmod_contest/sqmod_contest.html @@ -0,0 +1,39 @@ +<div class="com_pbox sboard_pbox"> + <table class="sboardlist"> + <tr class="head"> + <th class="rank">名次</th> + <th class="nickname">昵稱</th> + <th class="ac">AC數</th> + <th class="score">總分</th> + </tr> + </table> +</div> +<div tab="pro" class="com_pbox pro_pbox"> + <table class="prolist"> + <tr class="head"> + <th class="no">#</th> + <th class="name">題目名稱</th> + <th class="bscore">最佳分數</th> + </tr> + </table> + <table class="stat"> + <tr class="user_prog"> + <td style="width:76px;">個人進度</td> + <td style="padding:0px 0px 0px 6px;"><div class="prog_box user_prog"> + <div class="pass"></div> + <div class="good"></div> + <div class="total"></div> + <div class="prog"></div> + </div></td> + </tr> + <tr class="team_prog" style="display:none;"> + <td style="width:76px;">小組進度</td> + <td style="padding:0px 0px 0px 6px;"><div class="prog_box team_prog"> + <div class="pass"></div> + <div class="good"></div> + <div class="total"></div> + <div class="prog"></div> + </div></td> + </tr> + </table> +</div> diff --git a/toj/sqmod/sqmod_contest/sqmod_contest.inc.php b/toj/sqmod/sqmod_contest/sqmod_contest.inc.php new file mode 100755 index 0000000..b045dae --- /dev/null +++ b/toj/sqmod/sqmod_contest/sqmod_contest.inc.php @@ -0,0 +1,289 @@ +<?php + +require_once('common.inc.php'); +require_once('square.inc.php'); +require_once('sqlib_scoreboard.inc.php'); + +const SQMODNAME = 'sqmod_contest'; + +const SCOREBOARD_ID_PROBSTAT = 1; +const SCOREBOARD_ID_SCOREBOARD = 2; + +function score_func($sqid, $proid, $best_score, $best_time, $is_ac, $ac_time, $tries_before_ac, $last_score, $last_status, $tries) +{ + $data = get_setting($sqid); + $fscore = 0; + + foreach($data->pro as $pro) + { + if($pro->proid == $proid && $pro->method == 'normal') + { + $fscore = $pro->score; + break; + } + if($pro->method == 'max') + { + foreach($pro->config as $cf) + { + foreach($cf as $sp) + { + if($sp[0] == $proid) + { + $fscore = $sp[1]; + break; + } + } + } + } + } + + $rscore = $best_score * $fscore / 100; + return $rscore; +} + +function get_pro_stat_uid($sqlc, $msqlc, $sqid, $sboard_id, $uid) +{ + //get user $uid solving status of square $sqid. $sboard_id can be set as a fixed value. + $sq = square::get($sqlc, $sqid); + if(!$sq)die('Eno_such_sq'); + + $data = sqlib_scoreboard::get_scoreboard_uid($sqlc, $msqlc, $sqid, $sboard_id, 'score_func', $sq->start_time, $sq->end_time, $uid); + + return $data[0]; +} + +function process_pro_stat($obj) +{ + $ret = array(); + foreach($obj->problem as $pro) + { + $ps = new stdClass(); + $ps->proid = $pro->proid; + $ps->is_ac = $pro->is_ac; + $ps->best_score = $pro->best_score; + //$ps->rank_score = $pro->rank_score; + $ps->tried = ($pro->tries > 0); + //array_push($ret, $ps); + $ret[$pro->proid] = $ps; + } + return $ret; +} + +function add_setting($sqid) +{ + mkdir('/srv/http/toj/center/sq/'.$sqid); +} +function del_setting($sqid) +{ + $sqdir = '/srv/http/toj/center/sq/'.$sqid.'/'; + unlink($sqdir.'setting'); + rmdir($sqdir); +} +function get_setting($sqid) +{ + $sqdir = '/srv/http/toj/center/sq/'.$sqid.'/'; + $cont = file_get_contents($sqdir.'setting'); + $data = json_decode($cont); + return $data; +} +function put_setting($sqid, $data) +{ + $sqdir = '/srv/http/toj/center/sq/'.$sqid.'/'; + file_put_contents($sqdir.'setting', json_encode($data)); +} + +function get_term($data, $sqid) +{ + return $data->term; +} + +function calc_score($stat, $data, $sqid) +{ + $prolist = $data->pro; + $ret = array(); + foreach($prolist as $pro) + { + $proid = $pro->proid; + $np = new stdClass(); + if($stat)$np = clone $stat[$proid]; + //else continue; + if(!$stat) + { + $np->proid = $proid; + $np->best_score = 0; + $np->tried = false; + $np->is_ac = false; + array_push($ret, $np); + continue; + } + $method = $pro->method; + //$np->full_score = $pro->score; + if($method == 'normal') + { + $np->best_score = $stat[$proid]->best_score / 100 * $pro->score; + } + if($method == 'max') + { + $score = 0; + $tis_ac = false; + foreach($pro->config as $conf) + { + //$np->best_score = json_encode($conf); + $nowscore = 0; + $is_ac = true; + foreach($conf as $unit) + { + $nowscore += $stat[$unit[0]]->best_score / 100 * $unit[1]; + $np->tried = $np->tried || $stat[$unit[0]]->tried; + if(!$stat[$unit[0]]->is_ac)$is_ac = false; + } + $score = max($score, $nowscore); + if($is_ac)$tis_ac = true; + } + $np->is_ac = $tis_ac; + $np->best_score = $score;// / 100 * $pro->score; + } + //$np->best_score = json_encode($np); + array_push($ret, $np); + } + //$stat[0]->best_score = json_encode($ret[0]); + return $ret; +} + +function process_pro_list($list, $data, $sqid) +{ + $prol = $data->pro; + $ret = array(); + foreach($prol as $pro) + { + $proid = $pro->proid; + $np = null; + foreach($list as $op) + { + if($op->proid == $proid) + { + $np = clone $op; + break; + } + } + $np->prono = $pro->prono; + $np->full_score = $pro->score; + if($pro->proname)$np->proname = $pro->proname; + array_push($ret, $np); + } + return $ret; +} + +function get_base_line($data, $sqid, $isteam) +{ + $ret = new stdClass(); + if($isteam) + { + $ret->total_score = $data->total_score; + $ret->pass_score = $data->pass_score_team; + $ret->good_score = $data->good_score_team; + } + else + { + $ret->total_score = $data->total_score; + $ret->pass_score = $data->pass_score; + $ret->good_score = $data->good_score; + } + + return $ret; +} + +function get_scoreboard($sqlc, $msqlc, $sqid, $sboard_id){ + $sq = square::get($sqlc, $sqid); + if(!$sq) + die('Eno_such_sq'); + + $data = sqlib_scoreboard::get_scoreboard($sqlc, $msqlc, $sqid, $sboard_id, 'score_func', $sq->start_time, $sq->end_time, 0, 65536); + + return $data; +} + +function calc_default_baseline($total_score) +{ + $ret = new stdClass(); + + $ret->pass_score = round($total_score * 0.6); + $ret->good_score = round($total_score * 0.8); + $ret->pass_score_team = round($total_score * 0.8); + $ret->good_score_team = round($total_score * 1); + + return $ret; +} + +function event_create($sqid) +{ + $set = array( + 'term' => 1, + 'pro' => [], + 'total_score' => 0, + 'pass_score' => 0, + 'good_score' => 0, + 'pass_score_team' => 0, + 'good_score_team' => 0 + ); + + add_setting($sqid); + put_setting($sqid, $set); +} +function event_destroy($sqid) +{ + del_setting($sqid); +} +function event_add_pro($sqid, $proid) +{ + $set = get_setting($sqid); + + $list = $set->pro; + for($idx = 0;$idx < count($list);$idx++){ + if($list[$idx]->proid == $proid) + return; + } + $list[$idx] = array( + "prono" => $idx + 1, + "proid" => $proid, + "score" => 100, + "method" => 'normal' + ); + $set->pro = $list; + $set->total_score += 100; + + $baseline = calc_default_baseline($set->total_score); + $set->pass_score = $baseline->pass_score; + $set->good_score = $baseline->good_score; + $set->pass_score_team = $baseline->pass_score_team; + $set->good_score_team = $baseline->good_score_team; + + put_setting($sqid, $set); +} +function event_del_pro($sqid, $proid) +{ + $set = get_setting($sqid); + + $list = $set->pro; + $idx = 0; + while($idx < count($list)){ + if($list[$idx]->proid == $proid){ + array_splice($list,$idx,1); + $set->total_score -= 100; + }else{ + $list[$idx]->prono = $idx + 1; + $idx++; + } + } + $set->pro = $list; + + $baseline = calc_default_baseline($set->total_score); + $set->pass_score = $baseline->pass_score; + $set->good_score = $baseline->good_score; + $set->pass_score_team = $baseline->pass_score_team; + $set->good_score_team = $baseline->good_score_team; + + put_setting($sqid, $set); +} + +?> diff --git a/toj/sqmod/sqmod_contest/sqmod_contest.js b/toj/sqmod/sqmod_contest/sqmod_contest.js new file mode 100755 index 0000000..bb8d9b8 --- /dev/null +++ b/toj/sqmod/sqmod_contest/sqmod_contest.js @@ -0,0 +1,425 @@ +var sqmod_contest = function(that,j_page){ + var sboard_pbox = new class_sqmod_contest_sboard_pbox(that.sqid,j_page); + var pro_pbox = new class_sqmod_contest_pro_pbox(that.sqid,j_page); + + that.node.url_chg = function(direct,url_upart,url_dpart){ + if(direct == 'in'){ + index.title_set('TOJ-' + that.sqname); + + index.tab_add('sboard','/toj/sq/' + that.sqid + '/sboard/','記分板'); + index.tab_add('pro','/toj/sq/' + that.sqid + '/pro/','題目'); + + if(url_dpart.length == 0){ + com.url_update('/toj/sq/' + that.sqid + '/pro/'); + return 'stop'; + } + }else if(direct == 'out'){ + index.tab_empty(); + } + + return 'cont'; + }; + + that.node.child_set(sboard_pbox.node); + that.node.child_set(pro_pbox.node); +}; + +var class_sqmod_contest_sboard_pbox = function(sqid,j_page){ + var that = this; + var j_pbox = j_page.find('div.sboard_pbox'); + var j_table = j_pbox.find('table.sboardlist'); + var refresh_flag = false; + + var sboard_refresh = function(){ + if(refresh_flag == false){ + return; + } + + $.post('/toj/sqmod/sqmod_contest/sqmod_contest.php',{'action':'get_prolist','data':JSON.stringify({'sqid':sqid})},function(res){ + var i; + var prolist; + var proo; + + var tds; + var j_head; + var j_td; + var j_a; + + if(res[0] != 'E'){ + prolist = JSON.parse(res); + + j_table.css('width',(486 + prolist.length * 123) + 'px'); + + j_head = j_table.find('tr.head'); + tds = j_head.find('td.pro'); + for(i = 0;i < prolist.length;i++){ + proo = prolist[i]; + if(i < tds.length){ + j_td = $(tds[i]); + }else{ + j_td = $('<td class="pro"><a></a></td>'); + j_head.append(j_td); + } + + j_a = j_td.find('a'); + j_a.text(proo.proid); + j_a.attr('href','/toj/pro/' + proo.proid + '/'); + } + for(;i < tds.length;i++){ + $(tds[i]).remove(); + } + + $.post('/toj/sqmod/sqmod_contest/sqmod_contest.php',{'action':'get_scoreboard','data':JSON.stringify({'sqid':sqid})},function(res){ + var i; + var j; + var reto; + var start_time + var sboard_list; + var sboardo; + var proo; + var total_ac; + var total_score; + var duration; + var use_time; + + var trs; + var tds; + var j_item; + var j_a; + var j_score; + + if(res[0] != 'E'){ + reto = JSON.parse(res); + start_time = reto.start_time; + sboard_list = reto.list; + + trs = j_table.find('tr.item'); + for(i = 0;i < sboard_list.length;i++){ + sboardo = sboard_list[i]; + + if(i < trs.length){ + j_item = $(trs[i]); + }else{ + j_item = $('<tr class="item"><td class="rank"></td><td class="nickname"><a></a></td><td class="ac"></td><td class="score"></td></tr>'); + j_table.append(j_item); + } + + j_a = j_item.find('td.nickname > a'); + j_a.text(sboardo.nickname); + j_a.attr('href','/toj/user/' + sboardo.uid + '/'); + + if(sboardo.rank == -1){ + j_item.find('td.rank').text('-'); + }else{ + j_item.find('td.rank').text(sboardo.rank); + } + + tds = j_item.find('td.pro'); + for(j = tds.length;j < prolist.length;j++){ + j_item.append($('<td class="pro"><span class="score"></span><sup class="try"></sup><sub class="time"></sub></td>')); + } + for(;j < tds.length;j++){ + $(tds[j]).remove(); + } + + total_ac = 0; + total_score = 0; + tds = j_item.find('td.pro'); + for(j = 0;j < prolist.length;j++){ + j_td = $(tds[j]); + if(!(prolist[j].proid in sboardo.problem) || sboardo.problem[prolist[j].proid].tries == 0){ + j_td.find('span.score').text('') + j_td.find('sup.try').text(''); + j_td.find('sub.time').text(''); + }else{ + proo = sboardo.problem[prolist[j].proid]; + + j_score = j_td.find('span.score'); + if(proo.is_ac == true){ + j_score.css('color',RESULTCOLOR[0]); + total_ac++; + + if(start_time != null){ + duration = new Date(com.get_date(proo.ac_time) - com.get_date(start_time)).getTime(); + j_td.find('sub.time').text(com.get_durstring(duration,true)); + } + }else{ + j_score.css('color',null); + } + total_score += proo.best_score; + + j_score.text(proo.best_score) + j_td.find('sup.try').text(proo.tries_before_ac); + } + } + j_item.find('td.ac').text(total_ac); + j_item.find('td.score').text(total_score); + } + for(;i < trs.length;i++){ + trs[i].remove(); + } + } + + setTimeout(sboard_refresh,5000); + }); + } + }); + }; + + that.node = new vus.node('sboard'); + + that.__super(); + + that.node.url_chg = function(direct,url_upart,url_dpart){ + var reto; + + if(direct == 'in'){ + index.tab_hl('sboard'); + + refresh_flag = true; + sboard_refresh(); + + that.fadein(j_pbox); + }else if(direct == 'out'){ + index.tab_ll('sboard'); + that.fadeout(j_pbox); + + refresh_flag = false; + + j_table.find('tr.item').remove(); + j_table.find('tr.head > td.pro').remove(); + } + }; +}; __extend(class_sqmod_contest_sboard_pbox,class_com_pbox); + +var class_sqmod_contest_pro_pbox = function(sqid,j_page){ + var that = this; + var j_pbox = j_page.find('div.pro_pbox'); + var promap = null; + + var pro_listset = function(j_item,proo){ + var i; + + var bscore; + var fscore; + var ratio; + var j_a; + var j_team; + + if(proo != null){ + j_item.attr('proid',proo.proid); + + j_item.find('td.no').text(proo.prono); + j_a = j_item.find('td.name > a'); + j_a.attr('href','/toj/pro/' + proo.proid + '/'); + j_a.text(proo.proname); + + bscore = proo.bscore; + fscore = proo.full_score; + j_item.find('td.bscore').text(Math.floor(bscore) + ' / ' + Math.floor(fscore)); + + if(proo.tried == false){ + j_item.css('border-color','#1C1C1C'); + }else{ + ratio = bscore / fscore; + + if(ratio < 0.6){ + j_item.css('border-color','#FF0000'); + }else if(ratio < 0.8){ + j_item.css('border-color','#00FF00'); + }else if(ratio < 1){ + j_item.css('border-color','#FFFF00'); + }else{ + j_item.css('border-color','#FFFFFF'); + } + } + + j_item.find('td.team').remove(); + for(i = 0;i < proo.tscore.length;i++){ + j_team = $('<td class="team"></td>'); + j_team.text(Math.floor(proo.tscore[i])); + j_item.append(j_team); + } + } + }; + var pro_listnew = function(proo){ + var j_item; + + j_item = $('<tr class="item"><td class="no"></td><td class="name"><a></a></td><td class="bscore"></td></tr>'); + pro_listset(j_item,proo); + + return j_item; + }; + var prog_set = function(j_progbox,baseline,totalscore){ + var off; + var ratio; + var j_prog; + + off = 0; + ratio = baseline.pass_score * 100 / baseline.total_score; + j_prog = j_progbox.find('div.pass'); + j_prog.css('width',ratio + '%'); + j_prog.html(Math.floor(baseline.pass_score) + ' '); + off += ratio; + ratio = (baseline.good_score - baseline.pass_score) * 100 / baseline.total_score; + j_prog = j_progbox.find('div.good'); + j_prog.css('left',off + '%'); + j_prog.css('width',ratio + '%'); + j_prog.html(Math.floor(baseline.good_score) + ' '); + off += ratio; + ratio = 100 - off; + j_prog = j_progbox.find('div.total'); + j_prog.css('left',off + '%'); + j_prog.css('width',ratio + '%'); + j_prog.html(Math.floor(baseline.total_score) + ' '); + + ratio = totalscore * 100 / baseline.total_score; + j_prog = j_progbox.find('div.prog'); + j_prog.css('width',ratio + '%'); + j_prog.html(Math.floor(totalscore) + ' '); + if(totalscore < baseline.pass_score){ + ratio = totalscore / baseline.pass_score; + j_prog.css('background-color','rgba(255,' + Math.round(64 * ratio) + ',0,0.8)'); + }else if(totalscore < baseline.good_score){ + ratio = (totalscore - baseline.pass_score) / (baseline.good_score - baseline.pass_score); + j_prog.css('background-color','rgba(' + Math.round(128 * ratio) + ',255,0,0.8)'); + }else if(totalscore < baseline.total_score){ + ratio = (totalscore - baseline.good_score) / (baseline.total_score - baseline.good_score); + j_prog.css('background-color','rgba(255,255,' + Math.round(128 * ratio) + ',0.8)'); + }else{ + j_prog.css('background-color','rgba(255,255,255,0.8)'); + } + } + var prostat_refresh = function(){ + if(refresh_flag == false){ + return; + } + + $.post('/toj/sqmod/sqmod_contest/sqmod_contest.php',{'action':'get_user_stat','data':JSON.stringify({'sqid':sqid,'display_team':true})},function(res){ + var i; + var j; + + var reto; + var team; + var teamo; + var prostat; + var prostato; + var proo; + var user_total; + var team_total; + var maxscore; + var j_list; + var j_head; + var j_team; + var j_a; + var j_item; + + if(res[0] != 'E'){ + reto = JSON.parse(res); + team = reto.team; + prostat = reto.prostat; + + j_list = j_pbox.find('table.prolist'); + if(team != undefined){ + j_head = j_list.find('tr.head'); + j_head.find('th.team').remove(); + for(i = 0;i < team.length;i++){ + teamo = team[i]; + + j_team = $('<th class="team"><a></a></th>'); + j_a = j_team.find('a'); + j_a.attr('href','/toj/user/' + teamo.uid + '/') + j_a.text(teamo.name); + + for(j = 0;j < teamo.prostat.length;j++){ + if(teamo.prostat[j].tried == true){ + promap[teamo.prostat[j].proid].tscore[i] = teamo.prostat[j].best_score; + }else{ + promap[teamo.prostat[j].proid].tscore[i] = 0; + } + } + + j_head.append(j_team); + } + + j_pbox.find('table.stat tr.team_prog').show(); + } + + user_total = 0; + team_total = 0; + for(i = 0;i < prostat.length;i++){ + prostato = prostat[i]; + proo = promap[prostato.proid]; + proo.bscore = prostato.best_score; + proo.tried = prostato.tried; + user_total += prostato.best_score; + j_item = j_list.find('[proid = "' + prostato.proid + '"]'); + if(j_item.length > 0){ + pro_listset(j_item,proo); + } + + maxscore = proo.bscore; + for(j = 0;j < proo.tscore.length;j++){ + maxscore = Math.max(maxscore,proo.tscore[j]); + } + team_total += maxscore; + } + + prog_set(j_pbox.find('table.stat div.user_prog'),reto.base_line,user_total); + if(team != undefined){ + prog_set(j_pbox.find('table.stat div.team_prog'),reto.team_base_line,team_total); + } + + setTimeout(prostat_refresh,2000); + } + }); + }; + + that.node = new vus.node('pro'); + + that.__super(); + + that.node.url_chg = function(direct,url_upart,url_dpart){ + if(direct == 'in'){ + index.tab_hl('pro'); + that.fadein(j_pbox); + refresh_flag = true; + + $.post('/toj/sqmod/sqmod_contest/sqmod_contest.php',{'action':'get_prolist','data':JSON.stringify({'sqid':sqid})},function(res){ + var i; + var reto; + var proo; + var j_list; + var j_item; + + if(res[0] != 'E'){ + reto = JSON.parse(res); + + promap = new Array; + j_list = j_pbox.find('table.prolist'); + for(i = 0;i < reto.length;i++){ + proo = reto[i]; + proo.bscore = 0; + proo.tscore = new Array; + proo.tried = false; + if(proo.hidden == false || user.level == -1){ + promap[proo.proid] = proo; + j_item = pro_listnew(proo); + j_list.append(j_item); + } + } + + prostat_refresh(); + } + }); + }else if(direct == 'out'){ + index.tab_ll('pro'); + that.fadeout(j_pbox); + refresh_flag = false; + + j_pbox.find('table.prolist tr.item').remove(); + } + + return 'cont'; + }; +}; __extend(class_sqmod_contest_pro_pbox,class_com_pbox); diff --git a/toj/sqmod/sqmod_contest/sqmod_contest.php b/toj/sqmod/sqmod_contest/sqmod_contest.php new file mode 100755 index 0000000..f999cfa --- /dev/null +++ b/toj/sqmod/sqmod_contest/sqmod_contest.php @@ -0,0 +1,123 @@ +<?php +//ini_set("display_errors", "On"); + +require_once('common.inc.php'); +require_once('user.inc.php'); +require_once('square.inc.php'); +require_once('sqmod_contest.inc.php'); +require_once('team.inc.php'); +require_once('sqlib_scoreboard.inc.php'); + +$sqlc = db_connect(); +$msqlc = db_connect('toj_mod'); + +$action = $_POST['action']; +$data = $_POST['data']; + +if(strlen($action)==0) + die('Eno_action'); +if($action == 'get_prolist') +{ + $dt = json_decode($data); + $sqid = intval($dt->sqid); + if(square::get_sqmod($sqlc, $sqid) != SQMODNAME) + die('Eerror_sqid_this_mod'); + if(!sec_is_login()) + die('Enot_login'); + $uid = intval($_COOKIE['uid']); + if(square::get_user_relationship($sqlc, $uid, $sqid) < SQUARE_USER_ACTIVE) + die('Ecannot_view_sq'); + + $list = square::get_pro_list($sqlc, $sqid); + if(!$list) + die('Eno_problem'); + $data = get_setting($sqid); + $nlist = process_pro_list($list, $data, $sqid); + echo(json_encode($nlist)); +} +if($action == 'get_user_stat') +{ + $dt = json_decode($data); + $sqid = intval($dt->sqid); + $display_team = $dt->display_team; + if(square::get_sqmod($sqlc, $sqid) != SQMODNAME) + die('Eerror_sqid_this_mod'); + if(!sec_is_login()) + die('Enot_login'); + $uid = intval($_COOKIE['uid']); + if(square::get_user_relationship($sqlc, $uid, $sqid) < SQUARE_USER_ACTIVE) + die('Ecannot_view_sq'); + + $data = get_setting($sqid); + + $ret = new stdClass(); + $prostat = get_pro_stat_uid($sqlc, $msqlc, $sqid, SCOREBOARD_ID_PROBSTAT, $uid); + $tmpstat = process_pro_stat($prostat); + $ret->prostat = calc_score($tmpstat, $data, $sqid); + $ret->base_line = get_base_line($data, $sqid, false); + + if($display_team) + { + $term = get_term($data, $sqid); + $teamid = intval(get_teamid($msqlc, $term, $uid)); + if($teamid) + { + $ret->team_base_line = get_base_line($data, $sqid, true); + $members = get_team_member($msqlc, $term, $teamid); + $arr = array(); + foreach($members as $mem) + { + if($mem->uid == $uid)continue; + $tmpstat = process_pro_stat(get_pro_stat_uid($sqlc, $msqlc, $sqid, SCOREBOARD_ID_PROBSTAT, $mem->uid)); + $mem->prostat = calc_score($tmpstat, $data, $sqid); + array_push($arr, $mem); + } + $ret->team = $arr; + $ret->teamid = $teamid; + } + } + echo(json_encode($ret)); +} +if($action == 'get_scoreboard'){ + $dt = json_decode($data); + $sqid = intval($dt->sqid); + + $sqo = square::get($sqlc, $sqid); + if($sqo == NULL || $sqo->sqmodname != SQMODNAME) + die('Eerror_sq_error'); + if(!sec_is_login()) + die('Enot_login'); + $uid = intval($_COOKIE['uid']); + if(square::get_user_relationship($sqlc, $uid, $sqid) < SQUARE_USER_ACTIVE) + die('Ecannot_view_sq'); + + $list = get_scoreboard($sqlc, $msqlc, $sqid, SCOREBOARD_ID_SCOREBOARD); + $user_map = array(); + for($idx = 0;$idx < count($list);$idx++){ + $list[$idx]->nickname = user::get_nickname($sqlc, $list[$idx]->uid); + $user_map[$list[$idx]->uid] = true; + } + + $user_list = square::get_user_list($sqlc, $sqid); + for($idx = 0;$idx < count($user_list);$idx++){ + if(!array_key_exists($user_list[$idx]->uid,$user_map)){ + array_push($list,array( + 'uid' => $user_list[$idx]->uid, + 'nickname' => $user_list[$idx]->nickname, + 'rank' => -1, + 'rank_score' => 0, + 'problem' => [] + )); + } + } + + echo(json_encode(array( + 'start_time' => $sqo->start_time, + 'list' => $list + ))); +} + +db_close($sqlc); +db_close($msqlc); + +?> diff --git a/toj/sqmod/sqmod_contest/team.inc.php b/toj/sqmod/sqmod_contest/team.inc.php new file mode 100755 index 0000000..3effc0e --- /dev/null +++ b/toj/sqmod/sqmod_contest/team.inc.php @@ -0,0 +1,37 @@ +<?php + +require_once('../../php/common.inc.php'); + +const TEAM_TYPE_BOY = 1; +const TEAM_TYPE_GIRL = 2; +const TEAM_TYPE_COL = 3; +const TEAM_TYPE_TEA = 4; + +function get_teamid($msqlc, $term, $uid) +{ + //Return the teamid of $uid. False if not exists. + $sqlstr = 'SELECT "teamid" FROM "sqmod_sprout_team" WHERE "term"=$1 AND "uid"=$2;'; + $sqlarr = array($term, $uid); + $res = pg_query_params($msqlc, $sqlstr, $sqlarr); + $teamid = pg_fetch_result($res, 0); + return $teamid; +} + +function get_team_member($msqlc, $term, $teamid) +{ + //Return all team member uid, level of team $teamid. False if not exists. + $sqlstr = 'SELECT "sqmod_sprout_team"."uid", "sqmod_sprout_team"."level", "sqmod_sprout_student"."name" FROM "sqmod_sprout_team" INNER JOIN "sqmod_sprout_student" ON "sqmod_sprout_team"."uid"="sqmod_sprout_student"."uid" WHERE "sqmod_sprout_team"."term"=$1 AND "sqmod_sprout_team"."teamid"=$2 ORDER BY "sqmod_sprout_team"."level" DESC, "sqmod_sprout_team"."uid";'; + $sqlarr = array($term, $teamid); + $res = pg_query_params($msqlc, $sqlstr, $sqlarr); + $ret = array(); + while($obj = pg_fetch_object($res)) + { + $obj->uid = intval($obj->uid); + $obj->level = intval($obj->level); + array_push($ret, $obj); + } + return $ret; +} + + +?> diff --git a/toj/sqmod/sqmod_test/sqmod_test.inc.php b/toj/sqmod/sqmod_test/sqmod_test.inc.php index f7e5dca..c331a3f 100644..100755 --- a/toj/sqmod/sqmod_test/sqmod_test.inc.php +++ b/toj/sqmod/sqmod_test/sqmod_test.inc.php @@ -1,8 +1,8 @@ <?php -require_once('../../php/common.inc.php'); -require_once('../../php/square.inc.php'); -require_once('../../php/sqlib_scoreboard.inc.php'); +require_once('common.inc.php'); +require_once('square.inc.php'); +require_once('sqlib_scoreboard.inc.php'); const SQMODNAME = 'sqmod_test'; @@ -68,6 +68,16 @@ function process_pro_stat($obj) return $ret; } +function add_setting($sqid) +{ + mkdir('/srv/http/toj/center/sq/'.$sqid); +} +function del_setting($sqid) +{ + $sqdir = '/srv/http/toj/center/sq/'.$sqid.'/'; + unlink($sqdir.'setting'); + rmdir($sqdir); +} function get_setting($sqid) { $sqdir = '/srv/http/toj/center/sq/'.$sqid.'/'; @@ -75,6 +85,11 @@ function get_setting($sqid) $data = json_decode($cont); return $data; } +function put_setting($sqid, $data) +{ + $sqdir = '/srv/http/toj/center/sq/'.$sqid.'/'; + file_put_contents($sqdir.'setting', json_encode($data)); +} function get_term($data, $sqid) { @@ -177,4 +192,87 @@ function get_base_line($data, $sqid, $isteam) return $ret; } +function calc_default_baseline($total_score) +{ + $ret = new stdClass(); + + $ret->pass_score = round($total_score * 0.6); + $ret->good_score = round($total_score * 0.8); + $ret->pass_score_team = round($total_score * 0.8); + $ret->good_score_team = round($total_score * 1); + + return $ret; +} + +function event_create($sqid) +{ + $set = array( + 'term' => 1, + 'pro' => [], + 'total_score' => 0, + 'pass_score' => 0, + 'good_score' => 0, + 'pass_score_team' => 0, + 'good_score_team' => 0 + ); + + add_setting($sqid); + put_setting($sqid, $set); +} +function event_destroy($sqid) +{ + del_setting($sqid); +} +function event_add_pro($sqid, $proid) +{ + $set = get_setting($sqid); + + $list = $set->pro; + for($idx = 0;$idx < count($list);$idx++){ + if($list[$idx]->proid == $proid) + return; + } + $list[$idx] = array( + "prono" => $idx + 1, + "proid" => $proid, + "score" => 100, + "method" => 'normal' + ); + $set->pro = $list; + $set->total_score += 100; + + $baseline = calc_default_baseline($set->total_score); + $set->pass_score = $baseline->pass_score; + $set->good_score = $baseline->good_score; + $set->pass_score_team = $baseline->pass_score_team; + $set->good_score_team = $baseline->good_score_team; + + put_setting($sqid, $set); +} +function event_del_pro($sqid, $proid) +{ + $set = get_setting($sqid); + + $list = $set->pro; + $idx = 0; + while($idx < count($list)){ + if($list[$idx]->proid == $proid){ + array_splice($list,$idx,1); + $set->total_score -= 100; + }else{ + $list[$idx]->prono = $idx + 1; + $idx++; + } + } + $set->pro = $list; + + $baseline = calc_default_baseline($set->total_score); + $set->pass_score = $baseline->pass_score; + $set->good_score = $baseline->good_score; + $set->pass_score_team = $baseline->pass_score_team; + $set->good_score_team = $baseline->good_score_team; + + put_setting($sqid, $set); +} + ?> diff --git a/toj/sqmod/sqmod_test/sqmod_test.js b/toj/sqmod/sqmod_test/sqmod_test.js index 1792b77..4923ed0 100755 --- a/toj/sqmod/sqmod_test/sqmod_test.js +++ b/toj/sqmod/sqmod_test/sqmod_test.js @@ -5,9 +5,9 @@ var sqmod_test = function(that,j_page){ if(direct == 'in'){ index.title_set('TOJ-' + that.sqname); - index.tab_add('pro','/toj/sq/' + that.sqid + '/','題目'); + index.tab_add('pro','/toj/sq/' + that.sqid + '/pro/','題目'); - if(url_dpart[0] == ''){ + if(url_dpart.length == 0){ com.url_update('/toj/sq/' + that.sqid + '/pro/'); return 'stop'; } @@ -194,7 +194,9 @@ var class_sqmod_test_pro_pbox = function(sqid,j_page){ } prog_set(j_pbox.find('table.stat div.user_prog'),reto.base_line,user_total); - prog_set(j_pbox.find('table.stat div.team_prog'),reto.team_base_line,team_total); + if(team != undefined){ + prog_set(j_pbox.find('table.stat div.team_prog'),reto.team_base_line,team_total); + } setTimeout(prostat_refresh,2000); } diff --git a/toj/sqmod/sqmod_test/sqmod_test.php b/toj/sqmod/sqmod_test/sqmod_test.php index 3665dbd..341daae 100755 --- a/toj/sqmod/sqmod_test/sqmod_test.php +++ b/toj/sqmod/sqmod_test/sqmod_test.php @@ -1,11 +1,11 @@ <?php //ini_set("display_errors", "On"); -require_once('../../php/common.inc.php'); -require_once('../../php/user.inc.php'); +require_once('common.inc.php'); +require_once('php/user.inc.php'); require_once('sqmod_test.inc.php'); require_once('team.inc.php'); -require_once('../../php/sqlib_scoreboard.inc.php'); +require_once('php/sqlib_scoreboard.inc.php'); $sqlc = db_connect(); $msqlc = db_connect('toj_mod'); diff --git a/toj/sqmod/sqmod_test/sqmod_test_man.php b/toj/sqmod/sqmod_test/sqmod_test_man.php deleted file mode 100755 index b65804c..0000000 --- a/toj/sqmod/sqmod_test/sqmod_test_man.php +++ /dev/null @@ -1,174 +0,0 @@ -<?php - -require_once('../../php/common.inc.php'); -require_once('../../php/square.inc.php'); -require_once('../../php/user.inc.php'); -require_once('../../php/sqlib_scoreboard.inc.php'); -require_once('sqmod_test.inc.php'); - -function get_sprout_data($msqlc, $uid, $term) -{ - $sqlstr = 'SELECT * FROM "sqmod_sprout_student" INNER JOIN "sqmod_sprout_team" ON "sqmod_sprout_student"."uid"="sqmod_sprout_team"."uid" WHERE "sqmod_sprout_student"."uid"=$1 AND "sqmod_sprout_team"."term"=$2;'; - $sqlarr = array($uid, $term); - $res = pg_query_params($sqlstr, $sqlarr); - $ret = pg_fetch_object($res); - return $ret; -} - -function trans_type($type) -{ - if($type==1)return '高中男'; - if($type==2)return '高中女'; - if($type==3)return '大學生'; - if($type==4)return '小老師'; - if($type==5)return '內測員'; - if($type==6)return '管理員'; -} - -function team_cmp($a, $b) -{ - if($a->sspd->teamid == $b->sspd->teamid)return ($a->sspd->type < $b->sspd->type); - //var_dump($a); - //echo($a->sspd->teamid.','.$b->sspd->teamid.'<br>'); - return $a->sspd->teamid > $b->sspd->teamid; -} - -function get_user_spent_time($sqlc, $sqid, $uid, $start_time = null, $end_time = null) -{ - if(!$start_time)$start_time = '1990-01-01 01:01:01'; - if(!$end_time)$end_time = '2222-02-02 02:02:02'; - $sqlstr = 'SELECT "submit_time" FROM "submit" WHERE "uid"=$1 AND "submit_time">=$2 AND "submit_time"<$3 AND "proid" IN (SELECT "proid" FROM "pro_sq" WHERE "sqid"=$4) ORDER BY "submit_time";'; - $sqlarr = array($uid, $start_time, $end_time, $sqid); - $res = pg_query_params($sqlc, $sqlstr, $sqlarr); - $arr = pg_fetch_all_columns($res, 0); - $last_time = 0; - $tot_time = 0; - $cnt = 0; - //return 3; - foreach($arr as $str) - { - $cnt += 1; - $time = strtotime($str); - //return $time/60; - $mid = 10 * 60; - $lng = 90 * 60; - - $nl_time = $time + $mid; - if($nl_time <= $last_time + $lng) - { - $tot_time += $nl_time - $last_time; - } - else - { - $tot_time += 2 * $mid; - } - - $last_time = $nl_time; - } - return array($tot_time, $cnt); -} - -$sqlc = db_connect(); -$msqlc = db_connect('toj_mod'); - -$sqid = intval($_GET['sqid']); -if(!$sqid) - die('Eno_sqid'); - -$sboard_id = 1; -$sq = square::get($sqlc, $sqid); -if(!$sq) - die('Eerror_sqid'); - -$stime = $sq->start_time; -$etime = $sq->end_time; - -$sbdata = sqlib_scoreboard::get_scoreboard($sqlc, $msqlc, $sqid, $sboard_id, 'score_func', $sq->start_time, $sq->end_time, 1, null); - -//var_dump($sbdata); - -$prol = ''; -foreach($sbdata[0]->problem as $pro) -{ - $prol = $prol.'<td align=center width=50>'.$pro->proid.'</td>'; -} - -$dt = get_setting($sqid); -$base = get_base_line($dt, $sqid, false); -$term = get_term($dt, $sqid); - -echo('<meta http-equiv="Content-Type" content="text/html; charset=utf8">'); -echo('<table border = 1>'); -echo('<h align=center><td>rank</td><td>uid</td><td>Nickname</td><td>Name</td><td>StuNo.</td><td>Team</td><td>Type</td><td>Total</td>'.$prol.'<td>Sub.</td><td>Est. Time</td></h>'); - -$teamsc = array(); - -foreach($sbdata as $usr) -{ - $usr->sspd = get_sprout_data($msqlc, $usr->uid, $term); -} - -if($_GET['sort']=='team')usort($sbdata, 'team_cmp'); - -foreach($sbdata as $usr) -{ - $spd = $usr->sspd; - if($_GET['stu_only'] && !($spd->type>=1 && $spd->type<=4)) - continue; - echo('<tr align="center">'); - echo('<td>'.$usr->rank.'</td>'); - echo('<td>'.$usr->uid.'</td>'); - $user = user::get_from_uid($sqlc, $usr->uid); - $original_nickname=$user->nickname; - if(mb_strlen($user->nickname,'UTF-8')>7){ - $user->nickname=mb_substr($user->nickname,0,6,'UTF-8').'...'; - echo('<td title="'.str_replace("!","!",htmlspecialchars($original_nickname)).'">'.$user->nickname.'</td>'); - } else { - echo('<td>'.$user->nickname.'</td>'); - } - echo('<td>'.$spd->name.'</td>'); - echo('<td>'.$spd->stuno.'</td>'); - echo('<td>'.$spd->teamid.'</td>'); - echo('<td>'.trans_type($spd->type).'</td>'); - - $color = 'black'; - if($usr->rank_score >= $base->total_score)$color = 'gray'; - else if($usr->rank_score >= $base->good_score)$color = 'goldenrod'; - else if($usr->rank_score >= $base->pass_score)$color = 'limegreen'; - echo('<td><b><font color="'.$color.'">'.intval($usr->rank_score).'</font></b></td>'); - - - foreach($usr->problem as $pro) - { - if(!$pro->tries){echo('<td></td>');continue;} - - $clr = 'red'; - $b = false; - if($pro->is_ac){$clr = 'green';$b = true;} - else if($pro->best_score>=50)$clr = 'orange'; - echo('<td><font color="'.$clr.'">'.(b?'<b>':'').intval($pro->rank_score).(b?'</b>':'').'</font></td>'); - } - - $usr_time = get_user_spent_time($sqlc, $sqid, $usr->uid, $stime, $etime); - $uttmin = floor($usr_time[0] / 60); - $uttcnt = $usr_time[1]; - $tm_clr = 'black'; - $utmin = $uttmin % 60; - if($utmin<10)$utmin = '0'.$utmin; - $uthr = floor($uttmin/60); - if($uthr >= 2)$tm_clr = 'lime'; - if($uthr >= 6)$tm_clr = 'orange'; - if($uthr >= 10)$tm_clr = 'red'; - echo('<td>'.$uttcnt.'</td><td><font color="'.$tm_clr.'">'.$uthr.':'.$utmin.'</font></td>'); - - - echo('</tr>'); -} - -echo('</table>'); - - -db_close($sqlc); -db_close($msqlc); - -?> diff --git a/toj/sqmod/sqmod_test/team.inc.php b/toj/sqmod/sqmod_test/team.inc.php index 3effc0e..3effc0e 100644..100755 --- a/toj/sqmod/sqmod_test/team.inc.php +++ b/toj/sqmod/sqmod_test/team.inc.php |