From 24a6aabb6b4e9657f54c15eca9ca4a49f5bafc6b Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 29 Jul 2016 16:56:55 +0800 Subject: [PATCH 01/78] =?UTF-8?q?=E6=96=B0=E5=BB=BA=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E8=AF=B4=E6=98=8E=E5=88=97=E8=A1=A8=E5=9C=86=E7=82=B9=E5=A4=A7?= =?UTF-8?q?=E5=B0=8F=E4=B8=8E=E9=97=B4=E8=B7=9D=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/assets/wechat/new_project.html | 14 +++++++------- public/stylesheets/weui/weixin.css | 5 +++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/public/assets/wechat/new_project.html b/public/assets/wechat/new_project.html index f121a281a..e14f17508 100644 --- a/public/assets/wechat/new_project.html +++ b/public/assets/wechat/new_project.html @@ -8,16 +8,16 @@
项目功能特性(微信版) 更多项目特性(浏览器版)
diff --git a/public/stylesheets/weui/weixin.css b/public/stylesheets/weui/weixin.css index c67cd2a75..3738f1dc4 100644 --- a/public/stylesheets/weui/weixin.css +++ b/public/stylesheets/weui/weixin.css @@ -241,5 +241,6 @@ a.underline {text-decoration:underline;} /*20160729项目说明*/ -.project-intro {line-height:2; width:140px; margin-left:auto; margin-right:auto;} -.project-intro li {list-style:disc; margin-left:20px;} \ No newline at end of file +.project-intro {line-height:2; width:120px; margin-left:auto; margin-right:auto;} +.project-intro li {position:relative;} +.project-intro-dot {font-size:25px; font-weight:bold; position:absolute; left:-10px; top:-13px;} \ No newline at end of file From 634213797241c10ac67922e6f6a785e2e914825b Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 29 Jul 2016 17:06:25 +0800 Subject: [PATCH 02/78] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E5=8A=A8=E6=80=81?= =?UTF-8?q?=E6=96=87=E5=AD=97=E8=BF=87=E5=A4=9A=E6=98=BE=E7=A4=BA=E7=9C=81?= =?UTF-8?q?=E7=95=A5=E5=8F=B7=EF=BC=9A=E4=B8=AD=E6=96=87=E7=9C=81=E7=95=A5?= =?UTF-8?q?=E5=8F=B7=EF=BC=8C=E8=8B=B1=E6=96=87=E5=8D=95=E8=AF=8D=E5=8F=AF?= =?UTF-8?q?=E8=83=BD=E8=A2=AB=E6=8B=86=E5=88=86=E6=98=BE=E7=A4=BA=E7=9C=81?= =?UTF-8?q?=E7=95=A5=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../javascripts/wechat/directives/ellipsis.js | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/public/javascripts/wechat/directives/ellipsis.js b/public/javascripts/wechat/directives/ellipsis.js index a5dcfa293..d3a67c557 100644 --- a/public/javascripts/wechat/directives/ellipsis.js +++ b/public/javascripts/wechat/directives/ellipsis.js @@ -1,25 +1,25 @@ -/** - * Created by Tim on 7/22/16. - */ -//app.directive('ellipsisShow',["$timeout",function(timer){ -// return{ -// restrict: 'A', -// scope: {}, -// link: function(scope, element){ -// timer(function() { -// var textSplit = element.text().split(" "); -// var newContent = []; -// element.text(""); -// for (var i = 0; i < textSplit.length; i++) { -// newContent = newContent + " " + textSplit[i]; -// element.text(newContent); -// if(element[0].scrollHeight >= 100){ -// newContent = newContent + " " + textSplit[i+1] + " " + textSplit[i+2] + " " + textSplit[i+3] + " " + textSplit[i+4] + "..."; -// element.text(newContent); -// break; -// } -// } -// }); -// } -// } -//}]); \ No newline at end of file +/** + * Created by Tim on 7/22/16. + */ +app.directive('ellipsisShow',["$timeout",function(timer){ + return{ + restrict: 'A', + scope: {}, + link: function(scope, element){ + timer(function() { + var textSplit = element.text().split(""); + var newContent = []; + element.text(""); + for (var i = 0; i < textSplit.length; i++) { + newContent = newContent + textSplit[i]; + element.text(newContent); + if(element[0].scrollHeight >= 100){ + newContent = newContent + textSplit[i+1] + textSplit[i+2] + textSplit[i+3] + textSplit[i+4] + "..."; + element.text(newContent); + break; + } + } + }); + } + } +}]); \ No newline at end of file From 9a3acdd1dbd7661ec8e1f221dad3b2c7743c4309 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 29 Jul 2016 17:07:22 +0800 Subject: [PATCH 03/78] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/assets/wechat/app.html | 110 +++++++++++++++++----------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/public/assets/wechat/app.html b/public/assets/wechat/app.html index 00a55f553..74af26cfe 100644 --- a/public/assets/wechat/app.html +++ b/public/assets/wechat/app.html @@ -1,56 +1,56 @@ - - - - - 仅供本地调试使用 - - - - - - - - - - - - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + 仅供本地调试使用 + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From b100651185fdb149572db01412b26e513e8aef01 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 29 Jul 2016 17:09:53 +0800 Subject: [PATCH 04/78] =?UTF-8?q?=E6=8E=A7=E5=88=B6=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E8=BE=83=E5=A4=9A=E6=96=87=E5=AD=97=E5=90=8E=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E7=9C=81=E7=95=A5=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/javascripts/wechat/directives/ellipsis.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/javascripts/wechat/directives/ellipsis.js b/public/javascripts/wechat/directives/ellipsis.js index d3a67c557..1bc8491b3 100644 --- a/public/javascripts/wechat/directives/ellipsis.js +++ b/public/javascripts/wechat/directives/ellipsis.js @@ -14,7 +14,7 @@ app.directive('ellipsisShow',["$timeout",function(timer){ newContent = newContent + textSplit[i]; element.text(newContent); if(element[0].scrollHeight >= 100){ - newContent = newContent + textSplit[i+1] + textSplit[i+2] + textSplit[i+3] + textSplit[i+4] + "..."; + newContent = newContent + textSplit[i+1] + textSplit[i+2] + textSplit[i+3] + textSplit[i+4] + textSplit[i+5] + textSplit[i+6] + textSplit[i+7] + textSplit[i+8] + textSplit[i+9] + textSplit[i+10] + "..."; element.text(newContent); break; } From f0cf7adcdf081ff5d3938908f491407288632b76 Mon Sep 17 00:00:00 2001 From: yuanke <249218296@qq.com> Date: Mon, 1 Aug 2016 11:14:03 +0800 Subject: [PATCH 05/78] =?UTF-8?q?=E5=8A=A0=E5=85=A5=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E9=82=80=E8=AF=B7=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/mobile/apis/projects.rb | 10 ++-- app/api/mobile/entities/project.rb | 4 +- app/controllers/wechats_controller.rb | 6 +-- app/models/project.rb | 12 +++++ app/services/projects_service.rb | 16 +++++-- public/images/wechat/project.jpg | Bin 0 -> 129191 bytes .../javascripts/wechat/controllers/project.js | 4 +- .../wechat/controllers/project_list.js | 44 +++++++++--------- 8 files changed, 58 insertions(+), 38 deletions(-) create mode 100644 public/images/wechat/project.jpg diff --git a/app/api/mobile/apis/projects.rb b/app/api/mobile/apis/projects.rb index 5ab0878d0..bdb824694 100644 --- a/app/api/mobile/apis/projects.rb +++ b/app/api/mobile/apis/projects.rb @@ -167,12 +167,12 @@ module Mobile post "join" do authenticate! - # ps = ProjectsService.new - # status = ps.join_project({role: "5", openid: params[:openid], invite_code: params[:invite_code]}, current_user) - # - # present :status, status + ps = ProjectsService.new + status = ps.join_project({role: "5", openid: params[:openid], invite_code: params[:invite_code]}, current_user) + + {status:status, message:ProjectsService::JoinProjectError.message(status)} - {status:-1, message: '该功能将在近日开放,敬请期待!' } + # {status:-1, message: '该功能将在近日开放,敬请期待!' } end end diff --git a/app/api/mobile/entities/project.rb b/app/api/mobile/entities/project.rb index 3e1899caa..073f7cd0f 100644 --- a/app/api/mobile/entities/project.rb +++ b/app/api/mobile/entities/project.rb @@ -4,8 +4,8 @@ module Mobile expose :name expose :id expose :user_id - # expose :invite_code - # expose :qrcode + expose :invite_code + expose :qrcode expose :can_setting, if: lambda { |instance, options| options[:user] } do |instance, options| current_user = options[:user] diff --git a/app/controllers/wechats_controller.rb b/app/controllers/wechats_controller.rb index 23a443925..ebbe7c343 100644 --- a/app/controllers/wechats_controller.rb +++ b/app/controllers/wechats_controller.rb @@ -10,8 +10,8 @@ class WechatsController < ActionController::Base #邀请码 if join_class_request(request) sendBindClass(request, {invite_code: content}) - # elsif join_project_request(request) - # sendBindProject(request, {invite_code: content}) + elsif join_project_request(request) + sendBindProject(request, {invite_code: content}) else request.reply.text "您的意见已收到,非常感谢~ \n更多问题可以通过以下方式联系我们:\n官方QQ群:173184401\n我们会认真聆听您的意见和建议。" end @@ -284,7 +284,7 @@ class WechatsController < ActionController::Base content: "项目名称:#{project.name}\n发起人:#{creator.name}\n进入项目,和小伙伴轻松的研发吧!"} } return request.reply.news(news) do |article, n, index| # article is return object url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=#{Wechat.config.appid}&redirect_uri=#{ROOT_URL+'/wechat/user_activities#/project?id='+project.id.to_s}&response_type=code&scope=snsapi_base&state=myproject#wechat_redirect" - pic_url = "#{ROOT_URL}/images/wechat/class.jpg" + pic_url = "#{ROOT_URL}/images/wechat/project.jpg" article.item title: "#{n[:title]}", description: n[:content], pic_url: pic_url, diff --git a/app/models/project.rb b/app/models/project.rb index 67f010210..7085cf377 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -928,6 +928,18 @@ class Project < ActiveRecord::Base code end + def generate_qrcode + ticket = self.qrcode + if !ticket || ticket.size < 10 + response = Wechat.api.qrcode_create_scene(invite_code, 2592000) + logger.debug "response = #{response}" + self.qrcode = response['ticket'] + save! && reload + ticket = qrcode + end + ticket + end + private def after_parent_changed(parent_was) diff --git a/app/services/projects_service.rb b/app/services/projects_service.rb index 2441ea9e5..edc2f6816 100644 --- a/app/services/projects_service.rb +++ b/app/services/projects_service.rb @@ -114,7 +114,7 @@ class ProjectsService def join_project params,current_user status = -1 - project = project.find_by_invite_code(params[:invite_code]) if params[:invite_code] + project = Project.find_by_invite_code(params[:invite_code]) if params[:invite_code] if project if project[:is_delete] == 1 @@ -126,10 +126,18 @@ class ProjectsService else if params[:invite_code].present? members = [] - members << Member.new(:role_ids => [5], :user_id => current_user.id) + user_grades = [] + project_info = [] + + user_grades << UserGrade.new(:user_id => current_user.id, :project_id => project.id) + project.user_grades << user_grades unless user_grades.first.user_id.nil? + + members << Member.new(:role_ids => ["5"], :user_id => current_user.id) project.members << members - projectInfo = ProjectInfo.new(:user_id => current_user.id, :project_id => project.id) - projectInfo.save + + projectInfo << ProjectInfo.new(:user_id => current_user.id, :project_id => project.id) + project.project_infos << project_info + status = 0 else status = 4 diff --git a/public/images/wechat/project.jpg b/public/images/wechat/project.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5ac1cb67c3030d9de9ba8961549f5db2b4d075b1 GIT binary patch literal 129191 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≤No)labV3o!aTNQu-X zbwxDesLFl!Zjj+mr7&6iAtt`qkO8uM^9Zwm+h}NbGJ?H}qLE1Q4?t0ZVJCa6$dSeH^dCn?&xAT7_d}@Q|lDOJlGk$^JW`ztGNhX;xoFBl^xbZp;`U_@MRMh z`iuXC#od7h&Hu&8bm5m=wjrJ0g67Sg>HHH=@~i{pFcEG3LB1H?>zTQ$mAZp2AYP%0 z&ad|-hvJ*eYlqv_TyV!6r}_4@@uhgIDqbIyEo)d!)jx7sXVOlxpYf0QCj8Hb;(O1S z0H4mGBUFs61Jx26=N9x3F8rW$Dl0vaRwXVh;B(^0aap`L&?#&$Q|F3%TQtLv%YN~c zn`?^dMH1OpI z`E~t|w}gKc@BJTHE&jc!dXs`T>}Lq3PHPPM*ylyb%7jM0YQ~R-c+JkBl;nFJjUMEr zNuRA)pQ)25=xg|>lktdsPqWzo2A3T_~QEo8twLuhUTW4(4X~me|mMy1rnW5+KwWrUDvHq@PST%p6 zAcZI+)rCl!)tAa&96uZ(nO;PetG=n0OO{^kOV)Zt%Bw<&YS(lmFavuj+<;ebnxEj3x(0x`fK^YOtnf8;Q% zBKx<>@Rvatsy~KFXr+Vf!tH0Hp&(A-*ElV3Et)`F>PmX{Z-93EemIF?7OIp}R!6pL8uw+(TpJUo2cw2zGVyQk&ZtklscyueROWv?89UMR-1P<#na3WYlbGYUlaHyRpTuDlsjIm#5JV( zF&7VN=9s%hvAhM9s@8Q3TP{JrjQGbSD6%TXzrDNN9gRQKa7q87ZMmX4m{RBPr;8X> zU^I&yY`^fN`ZF0RU*fR}BED}WMcMcuFPvY+{UTDVkfeWZy1OgJRg1r~AS3GQ;oyLp9~K#|9t;U0slge zczen3peZAD=(@epvn@xz@SO>DUqsdMoGo(SBoS5#AS0Eby`2ch7q<&QT|M+NziK* zV9kdhtWPVUh;nb@R>V9^12j0TFk=4k*$g@3CmNbyDa>c8k5_TWw9Q-C#gj($_F)mq zrz`4);oLLc&4c)&>ragWrZOZAN>XK zra~xW?sj5tw?5}423|s;j>X{aFN1U#&KGyO`qz!n9r(AQgH#~6T-_f)gH7v`~7F^5$o&HDRL8Fkc_9G^0XYV8NJcQ(s!JWpCXvE;G>-=+F9N!^DNzVb7^6zu*iz7 zQtx+v2_^nA3N{i44`(}V?{#@??{FMKKNVlZG)7d+#(JPB{jQSl6IGTXf~d(CcC#0l;UoCabh^+686hF0yzym|h_Y=C^QW+==QDS~GPYmAs%^zV(z`cPN zLJyv+i9FV+EIB(eTi>R;sL@0fR;Fty&3fXpWmonuUvX3b)Kq7PeIgKz^{ws8zSNGn zT*Lgcw#wS3#ZMy;;WDpDZP>trbG;23!%2xf5jjJayB+O%BaW69sUWF57A2E4>ScHn z!p)=KHoK|oY}M!q<8@d(qwvigzsI%W3M;~!UEO~5KFR(zshly6U3Wt+EK5ev-hbIBa7ncQCvccjm4Pt?Z>K z=SW<)e-PZo2Za7#Y-X8JOq?w`xq8oJ7`t4cG*3obE&MnnD1D}$1683s zXPUD<;gi|4->44KH6%(Os*F#>kJmgsIPSc0(64x@pMOJQvX_IA6qI#`U!CGAb|+Mq z@e?20f!QwZ?+RpHEEo1|EYkMll?G~BcOnr(ugUEClLk08 z?u+ez51IpjB_azy9TLNicT^h*L5{3b>TX}JZnfVMPmPxnfHvuM)&|xsR~fG>vf;UZ z065~zXL+D#&p2Imh8v|KEYC#D91RO^B3f>a72pN8V`tWS1j89*dETn^3wX##5Uu*< z51>P^ixBD}#$ojb;NyJmc}fb}Vt`htB<7e@YRO?9V4?4cj~%UT61yml>~pfetOfHi zk5T5OU(a;Y5_>-PTDd2_=Z+$YtgKE{zvcS!+^Xfu(tgN)XK|V^mlKYS+l;k4vf0&? zH}?ijYWR_3;ZSMsuzd>*{XDgU1+m$zf01Hfb3AKf<^hk}wC;fLtsE`%+Mf!xHtkNo zp~*oMb&dnt+Gbb?&!_UrT-(f|4`I3Vhm8qbP`(~F44sPTvt>7;WBO7WXU_o zURulIo+h8G_nwG=ERhu@xIJhnSg#|{3tXuptAVSRU?2I_1L8$$q@PIB4(nRj?FBA| zsvm^{kN64G`%a5H&rTZJIF>1jAfo#voT_!Cg*7TTUkoOd^UTPS6{kc#Arr)WN3g^E z@uurJIXKBJ3Lnz7V286C{s6XF^<)92LyIK|kVA1$3pgIv{hD`f*^swx(_aYgbpBi|8Q!q8Qn7UhKnFv&vrO zi68OtI1hmNR<;B)rqQmaw7!XpncZ^=)(e(rmG)}ITj~dgwmndFF&iO|JDod6NFA#t zlc&VVcOi`de*jBo7xWZ#NuGKJO*vx|7B&0_fgZx`p4g?3!@;x1@DT?`V6Sd_V+Rb* zrz;u|xiyrA4vRsxK65j3e8SFn`-%;mt(Rbf)hG&bIR63M^K`x?%eH_^iRq~3S_TYG*VklNzZka{oczMCiSIKiNm!g!1QZ62TdFcosXL>juRv(ySs^WjIAWHS&RS$D2MNc8@yu6MPWgjJHjE@pBoF^xZXxNS55otb|Dy&DS`R|Kfm@w z%{kh~^+ClU_8SL4bF_h?qC7q1IuUFG+<`@!K&+dphxi$O-7TnYaCAO%{QU>ej&0}w z4usXu^7HH>cs!f#D_}VnzC2nX=-`5?&&0NdNiD9|u-6!a@N0qtQ3qO4*BaHKd=!3B zsRT1BC}pP={_Q;p(m&j*=aS-=bhadM6EPEf*mbENxss0}p0-YDlJ5Hn?f{{2CxjC* zdfCJC!ifXB=j%igAg4#WW}VfnX=5iutv{^Y)4pW}oN5{-4DY&K%%+KDy{XE3>-#cG zpUF#*BXFP%%yXKd9aFSy-rTw<`H@6kmn|yP=v~E6mha^>0KoUVh3dyh4>k%Rg1fh> z7@dQ4J202(rwn{<^sfaFxu3bIHD)Tncih1-Te`m95mJ_rWl-U7*|gAS@$^%XfnK`& zqcBz)evX2YI{H5Vx6a*|E`;%o%k+Xz>X&5?6 zqp=*K2_u3u=PxF-yw~rWR>m)%E{(%bS3GSGGrFx!*wcC~&!|Q8S?YvFvOvu7WrbC_ zRRw8VDXioPGG+wNvQ1;4saJt{SMzSm6`yr$ggjjIk}di1TfTry?~!~WIB3{GXYo*T zB)vK>2TvH`nBS;_IX?ifi3I*zCJgiC0+ZNUI$vV@`B?kND?!k0F(n#j3bLxha0k(^sbLvX7|S-nX&hD^?v`bGolg^TgG9oJE|a)sP!novz|bj zKOf#1_mF=O>Ntf6wD(#qeDbwCuO#GMna)S82k8&8gy==-L%*5ew$AUZBH0asjHsHo zV#%<4?H4h)DMGXAWMEls94&C=aWfzXmyDhrOT&0Q5Ar`+{cjppyx4Qa+VJ{y6Fy}}VV&3$`kOxMZ}PIN72Wd+tj*AQD@93)`_j?;afr6TpzJ12;*{ghN@GBwqf%0&9B zt<48*n~ax}tIkg_bbO#<}|7FhG+1aVvegMy5nU(!7Z-csT zDNoJvu+j_WJJeHiwFW;hECt#t%i?s zHcmX6^jYMr`}AWMQZ=Q&20h7m`FiE-kFT1RSti-kw{LseCVAnwjn~T;2LylfhfK0~ z8f$cH&At{U`}vM~$&Z)2Kj$_rk9xae=1HAGlh3)Ii@z%W;Q4V^{g3P3N&cty>@AKL z&TI+);pqS4VO+QBjcuK);tm=9o017^^-R3PwE5w7_bWn~h1KmM{1=kH+l4j(C-Cb# zPEW9@@3cFa_U-l5w6!^2e|!A@REK-qp1Q5=NAkqF{j zhesyZFWvLIEcy5r{GhJ--)xTRfHhm(2c6^1m)$+rP@X{?AfiZ*Z^vU&hP5_J```b~M|j z{a7zQF?`1YU=C>f?E|_Xukza}{hXaq%H5Ux&ldl)YF@ow^KJ5@%Gq!8KQmrhFZ)q_ z!N)V3%ueR?tj_kFeEyx*g4}TzXvQ7H T85bi3leuPLG?Ir@B;N!8*wigc literal 0 HcmV?d00001 diff --git a/public/javascripts/wechat/controllers/project.js b/public/javascripts/wechat/controllers/project.js index 0d6ca99f2..c4ff551a6 100644 --- a/public/javascripts/wechat/controllers/project.js +++ b/public/javascripts/wechat/controllers/project.js @@ -25,10 +25,10 @@ app.controller('ProjectController', ['$scope', 'config','$http','$timeout', 'aut //跳入邀请界面 vm.invite = function(){ - vm.alertService.showMessage('提示', "该功能将在近日开放,敬请期待!"); +// vm.alertService.showMessage('提示', "该功能将在近日开放,敬请期待!"); -// $location.path("/project_invite_code").search({id: projectid}); + $location.path("/project_invite_code").search({id: projectid}); }; //获取项目动态 diff --git a/public/javascripts/wechat/controllers/project_list.js b/public/javascripts/wechat/controllers/project_list.js index 058b7dde2..c5827f510 100644 --- a/public/javascripts/wechat/controllers/project_list.js +++ b/public/javascripts/wechat/controllers/project_list.js @@ -45,29 +45,29 @@ app.controller('ProjectListController', ['$scope', 'config', 'auth', '$http', '$ }; vm.joinProject = function () { - vm.alertService_1.showMessage('提示', "该功能将在近日开放,敬请期待!"); +// vm.alertService_1.showMessage('提示', "该功能将在近日开放,敬请期待!"); -// vm.alertService_3.showMessage('提示', '请输入6位项目邀请码(不区分大小写)', function(){ -// if (vm.alertService_3.invite && vm.alertService_3.invite.length == 6) { -// $http.post(config.apiUrl + "projects/join", { -// token: auth.token(), -// invite_code: vm.alertService_3.invite -// }).then(function (response) { -// console.log(response.data); -// if (response.data.status != 0) { -// vm.alertService_1.showMessage('提示', response.data.message); -// } else { -// vm.alertService_1.showMessage('提示', '加入项目成功'); -// vm.alertService_3.invite = ""; -// loadProjectList(); -// } -// }); -// } else { -// if(vm.alertService_3.invite){ -// vm.alertService_1.showMessage('提示', '邀请码格式不正确'); -// } -// } -// }); + vm.alertService_3.showMessage('提示', '请输入6位项目邀请码(不区分大小写)', function(){ + if (vm.alertService_3.invite && vm.alertService_3.invite.length == 6) { + $http.post(config.apiUrl + "projects/join", { + token: auth.token(), + invite_code: vm.alertService_3.invite + }).then(function (response) { + console.log(response.data); + if (response.data.status != 0) { + vm.alertService_1.showMessage('提示', response.data.message); + } else { + vm.alertService_1.showMessage('提示', '加入项目成功'); + vm.alertService_3.invite = ""; + loadProjectList(); + } + }); + } else { + if(vm.alertService_3.invite){ + vm.alertService_1.showMessage('提示', '邀请码格式不正确'); + } + } + }); }; vm.onSetting = function (project) { From bb0bfa21cc816003881d88d554311ce3ba31b7c6 Mon Sep 17 00:00:00 2001 From: yuanke <249218296@qq.com> Date: Mon, 1 Aug 2016 11:18:01 +0800 Subject: [PATCH 06/78] =?UTF-8?q?=E5=8A=A0=E5=85=A5=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E9=82=80=E8=AF=B7=E7=A0=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/wechats_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/wechats_controller.rb b/app/controllers/wechats_controller.rb index ebbe7c343..e0dcda93f 100644 --- a/app/controllers/wechats_controller.rb +++ b/app/controllers/wechats_controller.rb @@ -275,7 +275,7 @@ class WechatsController < ActionController::Base ps = ProjectsService.new status = ps.join_project({invite_code: project.invite_code}, user) if status[:state] != 0 - raise ProjectService::JoinProjectError.message(status) + raise ProjectsService::JoinProjectError.message(status) end creator = User.find(project.user_id) From 4c9e183cd05352f851d70e513654527286042a67 Mon Sep 17 00:00:00 2001 From: yuanke <249218296@qq.com> Date: Mon, 1 Aug 2016 11:24:27 +0800 Subject: [PATCH 07/78] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E8=8F=9C=E5=8D=95?= =?UTF-8?q?=E7=82=B9=E5=87=BB=E5=8A=A0=E5=85=A5=E9=A1=B9=E7=9B=AE=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/wechats_controller.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/controllers/wechats_controller.rb b/app/controllers/wechats_controller.rb index e0dcda93f..6ad45e14a 100644 --- a/app/controllers/wechats_controller.rb +++ b/app/controllers/wechats_controller.rb @@ -149,13 +149,13 @@ class WechatsController < ActionController::Base end on :click, with: 'JOIN_PROJECT' do |request, key| - request.reply.text "该功能将在近日开放,敬请期待!" - # uw = user_binded?(request[:FromUserName]) - # unless uw - # sendBind(request) - # else - # request.reply.text "请直接回复6位项目邀请码\n(不区分大小写):" - # end + # request.reply.text "该功能将在近日开放,敬请期待!" + uw = user_binded?(request[:FromUserName]) + unless uw + sendBind(request) + else + request.reply.text "请直接回复6位项目邀请码\n(不区分大小写):" + end end on :click, with: 'JOIN_CLASS' do |request, key| From 84f0069cbd579b4befad1883f8a7c5cecd1639ab Mon Sep 17 00:00:00 2001 From: yuanke <249218296@qq.com> Date: Mon, 1 Aug 2016 11:30:25 +0800 Subject: [PATCH 08/78] =?UTF-8?q?=E6=89=93=E5=BC=80=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E9=82=80=E8=AF=B7=E7=A0=81=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/services/projects_service.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/services/projects_service.rb b/app/services/projects_service.rb index edc2f6816..282f4f713 100644 --- a/app/services/projects_service.rb +++ b/app/services/projects_service.rb @@ -13,8 +13,8 @@ class ProjectsService #显示项目 def show_project(params,current_user) project = Project.find(params[:id]) - # project.generate_invite_code - # project.generate_qrcode + project.generate_invite_code + project.generate_qrcode project end From fa43924330b4aab00015afe461f3147dd69fa8b7 Mon Sep 17 00:00:00 2001 From: yuanke <249218296@qq.com> Date: Mon, 1 Aug 2016 13:54:10 +0800 Subject: [PATCH 09/78] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E4=BA=8C=E7=BB=B4=E7=A0=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/project.rb | 2 +- .../wechat/controllers/edit_class_member.js | 11 ++++------- .../wechat/controllers/edit_project_member.js | 11 ++++------- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/app/models/project.rb b/app/models/project.rb index 7085cf377..86f670f33 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -934,7 +934,7 @@ class Project < ActiveRecord::Base response = Wechat.api.qrcode_create_scene(invite_code, 2592000) logger.debug "response = #{response}" self.qrcode = response['ticket'] - save! && reload + save! ticket = qrcode end ticket diff --git a/public/javascripts/wechat/controllers/edit_class_member.js b/public/javascripts/wechat/controllers/edit_class_member.js index cddc183c5..2a9987290 100644 --- a/public/javascripts/wechat/controllers/edit_class_member.js +++ b/public/javascripts/wechat/controllers/edit_class_member.js @@ -30,13 +30,10 @@ app.controller('EditClassMemberController', ['$scope', '$http', 'auth', 'config' console.log(vm.current_edit_member); vm.cancel = function(){ - vm.alertService.showMessage('提示', '您确定不对角色进行变更吗?', function(){ -// rms.save("project_master_members",[]); -// rms.save("project_develop_members",[]); -// rms.save("project_report_members",[]); - window.history.back(); -// $location.path("/project").search({id: project_id}); - }); +// vm.alertService.showMessage('提示', '您确定不对角色进行变更吗?', function(){ +// window.history.back(); +// }); + window.history.back(); }; vm.edit_member_role = function(){ diff --git a/public/javascripts/wechat/controllers/edit_project_member.js b/public/javascripts/wechat/controllers/edit_project_member.js index 1063c0b13..cae768080 100644 --- a/public/javascripts/wechat/controllers/edit_project_member.js +++ b/public/javascripts/wechat/controllers/edit_project_member.js @@ -31,13 +31,10 @@ app.controller('EditProjectMemberController', ['$scope', '$http', 'auth', 'confi console.log(vm.current_edit_member); vm.cancel = function(){ - vm.alertService.showMessage('提示', '您确定不对角色进行变更吗?', function(){ -// rms.save("project_master_members",[]); -// rms.save("project_develop_members",[]); -// rms.save("project_report_members",[]); - window.history.back(); -// $location.path("/project").search({id: project_id}); - }); +// vm.alertService.showMessage('提示', '您确定不对角色进行变更吗?', function(){ +// window.history.back(); +// }); + window.history.back(); }; vm.edit_member_role = function(){ From 5272f20de87a156e9c34b6060305213f6d3ed2f7 Mon Sep 17 00:00:00 2001 From: daiao <358551898@qq.com> Date: Mon, 1 Aug 2016 13:56:37 +0800 Subject: [PATCH 10/78] =?UTF-8?q?=E5=8D=95=E4=BD=8D=E5=AE=A1=E6=A0=B8bug?= =?UTF-8?q?=E7=9A=84=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/admin_controller.rb | 24 +++++++++++-------- app/views/admin/has_applied_schools.html.erb | 6 ++--- .../users/_user_message_applied.html.erb | 2 +- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb index 935ca1d71..060f23ec4 100644 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/admin_controller.rb @@ -612,43 +612,44 @@ class AdminController < ApplicationController end end - # 获取申请的高校列表 - # status: 0 未审批; 1 已批阅; + # 单位审核 + # 未审批tab页 + # status: 0 未审批; 1 已批阅; 2已更改; 3拒绝; def applied_schools @name = params[:name] || "" condition = "#{@name.strip}".gsub(" ","") @apply_status = ApplyAddSchools.where("status = 0 and name like '%#{condition}%'").order('created_at desc') @apply_count = @apply_status.count - @apply_pages = Paginator.new @apply_count, 30, params['page'] || 1 @apply_status = paginateHelper @apply_status, 30 - @page = (params['page'] || 1).to_i - 1 + respond_to do |format| format.html end end + # 单位审核 + # 已审批tab页 def has_applied_schools @name = params[:name] || "" condition = "#{@name.strip}".gsub(" ","") @has_apply_status = ApplyAddSchools.where("(status = 1 or status = 2) and name like '%#{condition}%'").order('created_at desc') @has_apply_count = @has_apply_status.count - @has_apply_pages = Paginator.new @has_apply_count, 30, params['page'] || 1 @has_apply_status = paginateHelper @has_apply_status, 30 - @page = (params['page'] || 1).to_i - 1 + respond_to do |format| format.html end end - # 批准未审批的高校 + # 单位审核:批准 # 消息发送,发送对象为申请人 - # status: 0表示未批准; status:1表示已批准; status: 2表示已更改; status: 3表示已拒绝 + # status: 0表示未批准; status:1表示已批准; status: 2表示已更改; status: 3表示已拒绝; def approve_applied_schools applied_school = ApplyAddSchools.find params[:id] applied_school.update_column('status', 1) unless applied_school.nil? @@ -661,7 +662,7 @@ class AdminController < ApplicationController end end - # 更改申请的高校名称 + # 单位审核:更改 # REDO: 修改该字段 # REDO: 同步修改使用了改名称的用户单位 def edit_applied_schools @@ -686,6 +687,7 @@ class AdminController < ApplicationController redirect_to unapplied_schools_url end + # 单位审核:更改功能搜索合法学校弹框 def all_schools apply_schools = ApplyAddSchools.where("status != 1") apply_school_ids = apply_schools.empty? ? "(-1)" : "(" + apply_schools.map{|sc| sc.school_id}.join(',') + ")" @@ -704,7 +706,7 @@ class AdminController < ApplicationController end end - # 删除申请的高校 + # 单位审核:删除 # REDO: destroy关联删除 # REDO: 删除确认提示,是否删除 # REDO: 给申请人发送消息 @@ -717,6 +719,8 @@ class AdminController < ApplicationController user.update_column("school_id", nil) end applied_school.school.destroy + + # 跳转当前页面 if params[:tip] == "unapplied" redirect_to unapplied_schools_url elsif params[:tip] == "applied" diff --git a/app/views/admin/has_applied_schools.html.erb b/app/views/admin/has_applied_schools.html.erb index 5be3517c8..1b6341fb3 100644 --- a/app/views/admin/has_applied_schools.html.erb +++ b/app/views/admin/has_applied_schools.html.erb @@ -26,7 +26,7 @@ 单位名称 - + 申请者 @@ -59,8 +59,8 @@ <% unless apply.school_id.nil? %> <% school_name = School.where("id=?", apply.school_id).first %> - <%= school_name %> - + <%= school_name.name %> + <% end %> diff --git a/app/views/users/_user_message_applied.html.erb b/app/views/users/_user_message_applied.html.erb index e543f6cee..fbe422242 100644 --- a/app/views/users/_user_message_applied.html.erb +++ b/app/views/users/_user_message_applied.html.erb @@ -24,7 +24,7 @@ 系统提示 ">您添加新的高校(单位):

  • - <%= ma.applied.name %>的申请,因名称不合法,系统已将其更改为“<%= ma.name %>” + “<%= ma.applied.name %>”的申请,因名称不合法,系统已将其更改为“<%= ma.name %>”
  • <%= time_tag(ma.created_at).html_safe %>
  • <% elsif ma.status == 3 %> From 3bc696a5972f46598f5cd33902a85856acbd6803 Mon Sep 17 00:00:00 2001 From: cxt Date: Mon, 1 Aug 2016 13:57:55 +0800 Subject: [PATCH 11/78] =?UTF-8?q?=E7=94=B3=E8=AF=B7=E5=AD=A6=E6=A0=A1?= =?UTF-8?q?=E7=9A=84=E6=9B=B4=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/admin_controller.rb | 6 ++++-- db/schema.rb | 28 +++++++++++++++++++++++----- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb index 935ca1d71..0b165b7c5 100644 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/admin_controller.rb @@ -676,7 +676,9 @@ class AdminController < ApplicationController users.each do |user| user.update_column("school_id", school[0].id) end - aas.school.destroy + if aas.school_id != school[0].id.to_i + aas.school.destroy + end aas.update_attribute(:school_id, school[0].id) rescue Exception => e puts e @@ -687,7 +689,7 @@ class AdminController < ApplicationController end def all_schools - apply_schools = ApplyAddSchools.where("status != 1") + apply_schools = ApplyAddSchools.where("status = 0") apply_school_ids = apply_schools.empty? ? "(-1)" : "(" + apply_schools.map{|sc| sc.school_id}.join(',') + ")" if !params[:search].nil? search = "%#{params[:search].to_s.strip.downcase}%" diff --git a/db/schema.rb b/db/schema.rb index c7d918346..d8b93da88 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20160725091759) do +ActiveRecord::Schema.define(:version => 20160729124833) do create_table "activities", :force => true do |t| t.integer "act_id", :null => false @@ -52,9 +52,24 @@ ActiveRecord::Schema.define(:version => 20160725091759) do add_index "api_keys", ["access_token"], :name => "index_api_keys_on_access_token" add_index "api_keys", ["user_id"], :name => "index_api_keys_on_user_id" + create_table "applied_messages", :force => true do |t| + t.integer "user_id" + t.integer "applied_id" + t.string "applied_type" + t.integer "viewed", :default => 0 + t.integer "status", :default => 0 + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "name" + t.integer "applied_user_id" + t.integer "role" + t.integer "project_id" + end + create_table "applied_projects", :force => true do |t| - t.integer "project_id", :null => false - t.integer "user_id", :null => false + t.integer "project_id", :null => false + t.integer "user_id", :null => false + t.integer "role", :default => 0 end create_table "apply_add_schools", :force => true do |t| @@ -1106,9 +1121,10 @@ ActiveRecord::Schema.define(:version => 20160725091759) do end create_table "member_roles", :force => true do |t| - t.integer "member_id", :null => false - t.integer "role_id", :null => false + t.integer "member_id", :null => false + t.integer "role_id", :null => false t.integer "inherited_from" + t.integer "is_current", :default => 1 end add_index "member_roles", ["member_id"], :name => "index_member_roles_on_member_id" @@ -1539,6 +1555,8 @@ ActiveRecord::Schema.define(:version => 20160725091759) do t.integer "boards_reply_count", :default => 0 t.integer "visits", :default => 0 t.integer "hot", :default => 0 + t.string "invite_code" + t.string "qrcode" end add_index "projects", ["lft"], :name => "index_projects_on_lft" From c1bd3b6bf129b1febcf7ae0d4f86822b6ec42567 Mon Sep 17 00:00:00 2001 From: yuanke <249218296@qq.com> Date: Mon, 1 Aug 2016 14:30:31 +0800 Subject: [PATCH 12/78] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/wechats_controller.rb | 6 ++++++ app/services/projects_service.rb | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/controllers/wechats_controller.rb b/app/controllers/wechats_controller.rb index 6ad45e14a..bf4e1fade 100644 --- a/app/controllers/wechats_controller.rb +++ b/app/controllers/wechats_controller.rb @@ -8,6 +8,8 @@ class WechatsController < ActionController::Base # default text responder when no other match on :text do |request, content| #邀请码 + logger.debug "!!!!!!!!!!!fankui" + logger.info request if join_class_request(request) sendBindClass(request, {invite_code: content}) elsif join_project_request(request) @@ -43,11 +45,15 @@ class WechatsController < ActionController::Base # When subscribe user scan scene_id in public account on :scan, with: 'scene_id' do |request, ticket| + logger.debug "!!!!!!!!!!!scene_id" + logger.info request sendBindClass(request, {ticket: ticket}) end # When no any on :scan responder can match subscribe user scaned scene_id on :event, with: 'scan' do |request| + logger.debug "!!!!!!!!!!!scan" + logger.info request if request[:EventKey].present? sendBindClass(request, {ticket: request[:Ticket]}) end diff --git a/app/services/projects_service.rb b/app/services/projects_service.rb index 282f4f713..2d5e3bf08 100644 --- a/app/services/projects_service.rb +++ b/app/services/projects_service.rb @@ -135,7 +135,7 @@ class ProjectsService members << Member.new(:role_ids => ["5"], :user_id => current_user.id) project.members << members - projectInfo << ProjectInfo.new(:user_id => current_user.id, :project_id => project.id) + project_info << ProjectInfo.new(:user_id => current_user.id, :project_id => project.id) project.project_infos << project_info status = 0 From 2c86ae3eb21582ff7d378a2856be89a66f88303d Mon Sep 17 00:00:00 2001 From: yuanke <249218296@qq.com> Date: Mon, 1 Aug 2016 15:09:36 +0800 Subject: [PATCH 13/78] =?UTF-8?q?=E4=BA=8C=E7=BB=B4=E7=A0=81=E8=AF=86?= =?UTF-8?q?=E5=88=AB=20=E9=A1=B9=E7=9B=AE=E5=92=8C=E7=8F=AD=E7=BA=A7?= =?UTF-8?q?=E5=8C=BA=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/wechats_controller.rb | 45 +++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/app/controllers/wechats_controller.rb b/app/controllers/wechats_controller.rb index bf4e1fade..118aea0f2 100644 --- a/app/controllers/wechats_controller.rb +++ b/app/controllers/wechats_controller.rb @@ -8,8 +8,6 @@ class WechatsController < ActionController::Base # default text responder when no other match on :text do |request, content| #邀请码 - logger.debug "!!!!!!!!!!!fankui" - logger.info request if join_class_request(request) sendBindClass(request, {invite_code: content}) elsif join_project_request(request) @@ -45,16 +43,18 @@ class WechatsController < ActionController::Base # When subscribe user scan scene_id in public account on :scan, with: 'scene_id' do |request, ticket| - logger.debug "!!!!!!!!!!!scene_id" - logger.info request sendBindClass(request, {ticket: ticket}) end # When no any on :scan responder can match subscribe user scaned scene_id on :event, with: 'scan' do |request| - logger.debug "!!!!!!!!!!!scan" - logger.info request if request[:EventKey].present? + + + + + + sendBindClass(request, {ticket: request[:Ticket]}) end end @@ -215,6 +215,39 @@ class WechatsController < ActionController::Base end end + def checkTicket(request,params) + begin + uw = user_binded?(request[:FromUserName]) + if !uw + return sendBind(request) + end + + course = nil + course = Course.where(qrcode: params[:ticket]).first if params[:ticket] + course = Course.where(invite_code: params[:invite_code]).first if params[:invite_code] + + if course + return join_class(params, uw.user, request) + else + project = nil + project = Project.where(qrcode: params[:ticket]).first if params[:ticket] + project = Project.where(invite_code: params[:invite_code]).first if params[:invite_code] + if project + return join_project(params, uw.user, request) + end + end + + raise "该二维码已失效!" + + rescue => e + logger.error e.inspect + logger.error e.backtrace.join("\n") + return request.reply.text e + end + + + end + def default_msg(request) uw = user_binded?(request[:FromUserName]) if uw && uw.user From 08b8e3f1cb6bef57e441caa1daf27c3aa66a6dd1 Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 1 Aug 2016 15:21:23 +0800 Subject: [PATCH 14/78] =?UTF-8?q?=E5=8A=A0=E5=85=A5=E7=8F=AD=E7=BA=A7?= =?UTF-8?q?=EF=BC=8C=E9=A1=B9=E7=9B=AE=E5=BC=B9=E6=A1=86=E5=AE=9A=E4=BD=8D?= =?UTF-8?q?js=E9=87=8D=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../applied_join_project.js.erb | 2 +- .../applied_project_info.js.erb | 2 +- app/views/courses/join_private_courses.js.erb | 2 +- db/schema.rb | 4618 +++++++++-------- public/javascripts/application.js | 9 +- 5 files changed, 2328 insertions(+), 2305 deletions(-) diff --git a/app/views/applied_project/applied_join_project.js.erb b/app/views/applied_project/applied_join_project.js.erb index 5d9f7f87a..f090cb485 100644 --- a/app/views/applied_project/applied_join_project.js.erb +++ b/app/views/applied_project/applied_join_project.js.erb @@ -1,3 +1,3 @@ var htmlvalue = "<%= escape_javascript(render :partial => 'applied_join_project', locals: {:project_id => (@project.nil? ? nil : @project.id)}) %>"; -pop_box_new(htmlvalue,460,40,50); +pop_box_new(htmlvalue,460,190); diff --git a/app/views/applied_project/applied_project_info.js.erb b/app/views/applied_project/applied_project_info.js.erb index ab3cb396d..c1cc6176d 100644 --- a/app/views/applied_project/applied_project_info.js.erb +++ b/app/views/applied_project/applied_project_info.js.erb @@ -2,4 +2,4 @@ $("#join_in_project_applied").html('<%= escape_javascript( render :partial => 'projects/applied_status') %>'); <% end %> var htmlvalue = "<%= escape_javascript(render :partial => 'applied_project/applied_project_tip') %>"; -pop_box_new(htmlvalue,380,40,50); +pop_box_new(htmlvalue,380,166); diff --git a/app/views/courses/join_private_courses.js.erb b/app/views/courses/join_private_courses.js.erb index 14402a9ff..fc53970e4 100644 --- a/app/views/courses/join_private_courses.js.erb +++ b/app/views/courses/join_private_courses.js.erb @@ -1,2 +1,2 @@ var htmlvalue = "<%= escape_javascript(render :partial => 'join_private_course') %>"; -pop_box_new(htmlvalue,460,40,50); +pop_box_new(htmlvalue,460,220); diff --git a/db/schema.rb b/db/schema.rb index c7d918346..340e40350 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -1,2300 +1,2318 @@ -# encoding: UTF-8 -# This file is auto-generated from the current state of the database. Instead -# of editing this file, please use the migrations feature of Active Record to -# incrementally modify your database, and then regenerate this schema definition. -# -# Note that this schema.rb definition is the authoritative source for your -# database schema. If you need to create the application database on another -# system, you should be using db:schema:load, not running all the migrations -# from scratch. The latter is a flawed and unsustainable approach (the more migrations -# you'll amass, the slower it'll run and the greater likelihood for issues). -# -# It's strongly recommended to check this file into your version control system. - -ActiveRecord::Schema.define(:version => 20160725091759) do - - create_table "activities", :force => true do |t| - t.integer "act_id", :null => false - t.string "act_type", :null => false - t.integer "user_id", :null => false - t.integer "activity_container_id" - t.string "activity_container_type", :default => "" - t.datetime "created_at" - end - - add_index "activities", ["act_id", "act_type"], :name => "index_activities_on_act_id_and_act_type" - add_index "activities", ["user_id", "act_type"], :name => "index_activities_on_user_id_and_act_type" - add_index "activities", ["user_id"], :name => "index_activities_on_user_id" - - create_table "activity_notifies", :force => true do |t| - t.integer "activity_container_id" - t.string "activity_container_type" - t.integer "activity_id" - t.string "activity_type" - t.integer "notify_to" - t.datetime "created_on" - t.integer "is_read" - end - - add_index "activity_notifies", ["activity_container_id", "activity_container_type"], :name => "index_an_activity_container_id" - add_index "activity_notifies", ["created_on"], :name => "index_an_created_on" - add_index "activity_notifies", ["notify_to"], :name => "index_an_notify_to" - - create_table "api_keys", :force => true do |t| - t.string "access_token" - t.datetime "expires_at" - t.integer "user_id" - t.boolean "active", :default => true - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - add_index "api_keys", ["access_token"], :name => "index_api_keys_on_access_token" - add_index "api_keys", ["user_id"], :name => "index_api_keys_on_user_id" - - create_table "applied_projects", :force => true do |t| - t.integer "project_id", :null => false - t.integer "user_id", :null => false - end - - create_table "apply_add_schools", :force => true do |t| - t.string "name" - t.string "province" - t.string "city" - t.string "address" - t.string "remarks" - t.integer "school_id" - t.integer "status", :default => 0 - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "user_id" - end - - create_table "apply_homeworks", :force => true do |t| - t.integer "status" - t.integer "user_id" - t.integer "homework_common_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - add_index "apply_homeworks", ["homework_common_id"], :name => "index_apply_homeworks_on_homework_common_id" - add_index "apply_homeworks", ["user_id"], :name => "index_apply_homeworks_on_user_id" - - create_table "apply_project_masters", :force => true do |t| - t.integer "user_id" - t.string "apply_type" - t.integer "apply_id" - t.integer "status" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "apply_resources", :force => true do |t| - t.integer "status" - t.integer "user_id" - t.integer "attachment_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "container_id" - t.string "container_type" - t.text "content" - t.integer "apply_user_id" - end - - create_table "at_messages", :force => true do |t| - t.integer "user_id" - t.integer "at_message_id" - t.string "at_message_type" - t.boolean "viewed", :default => false - t.string "container_type" - t.integer "container_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "sender_id" - end - - add_index "at_messages", ["user_id"], :name => "index_at_messages_on_user_id" - - create_table "attachment_histories", :force => true do |t| - t.integer "container_id" - t.string "container_type" - t.string "filename", :default => "" - t.string "disk_filename", :default => "" - t.integer "filesize", :default => 0 - t.string "content_type", :default => "" - t.string "digest", :limit => 40, :default => "" - t.integer "downloads", :default => 0 - t.integer "author_id" - t.datetime "created_on" - t.string "description" - t.string "disk_directory" - t.integer "attachtype" - t.integer "is_public" - t.integer "copy_from" - t.integer "quotes" - t.integer "version" - t.integer "attachment_id" - t.integer "is_publish", :default => 1 - t.date "publish_time" - end - - create_table "attachments", :force => true do |t| - t.integer "container_id" - t.string "container_type", :limit => 30 - t.string "filename", :default => "", :null => false - t.string "disk_filename", :default => "", :null => false - t.integer "filesize", :default => 0, :null => false - t.string "content_type", :default => "" - t.string "digest", :limit => 40, :default => "", :null => false - t.integer "downloads", :default => 0, :null => false - t.integer "author_id", :default => 0, :null => false - t.datetime "created_on" - t.string "description" - t.string "disk_directory" - t.integer "attachtype", :default => 1 - t.integer "is_public", :default => 1 - t.integer "copy_from" - t.integer "quotes" - t.integer "is_publish", :default => 1 - t.date "publish_time" - end - - add_index "attachments", ["author_id"], :name => "index_attachments_on_author_id" - add_index "attachments", ["container_id", "container_type"], :name => "index_attachments_on_container_id_and_container_type" - add_index "attachments", ["created_on"], :name => "index_attachments_on_created_on" - - create_table "attachmentstypes", :force => true do |t| - t.integer "typeId", :null => false - t.string "typeName", :limit => 50 - end - - create_table "auth_sources", :force => true do |t| - t.string "type", :limit => 30, :default => "", :null => false - t.string "name", :limit => 60, :default => "", :null => false - t.string "host", :limit => 60 - t.integer "port" - t.string "account" - t.string "account_password", :default => "" - t.string "base_dn" - t.string "attr_login", :limit => 30 - t.string "attr_firstname", :limit => 30 - t.string "attr_lastname", :limit => 30 - t.string "attr_mail", :limit => 30 - t.boolean "onthefly_register", :default => false, :null => false - t.boolean "tls", :default => false, :null => false - t.string "filter" - t.integer "timeout" - end - - add_index "auth_sources", ["id", "type"], :name => "index_auth_sources_on_id_and_type" - - create_table "biding_projects", :force => true do |t| - t.integer "project_id" - t.integer "bid_id" - t.integer "user_id" - t.string "description" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.string "reward" - end - - create_table "bids", :force => true do |t| - t.string "name" - t.string "budget", :null => false - t.integer "author_id" - t.date "deadline" - t.text "description" - t.datetime "created_on", :null => false - t.datetime "updated_on", :null => false - t.integer "commit" - t.integer "reward_type" - t.integer "homework_type" - t.integer "parent_id" - t.string "password" - t.integer "is_evaluation" - t.integer "proportion", :default => 60 - t.integer "comment_status", :default => 0 - t.integer "evaluation_num", :default => 3 - t.integer "open_anonymous_evaluation", :default => 1 - end - - create_table "blog_comments", :force => true do |t| - t.integer "blog_id", :null => false - t.integer "parent_id" - t.string "title", :default => "", :null => false - t.text "content" - t.integer "author_id" - t.integer "comments_count", :default => 0, :null => false - t.integer "last_comment_id" - t.datetime "created_on", :null => false - t.datetime "updated_on", :null => false - t.boolean "locked", :default => false - t.integer "sticky", :default => 0 - t.integer "reply_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "blogs", :force => true do |t| - t.string "name", :default => "", :null => false - t.text "description" - t.integer "position", :default => 1 - t.integer "article_count", :default => 0, :null => false - t.integer "comments_count", :default => 0, :null => false - t.integer "last_comments_id" - t.integer "parent_id" - t.integer "author_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "homepage_id" - end - - create_table "boards", :force => true do |t| - t.integer "project_id", :null => false - t.string "name", :default => "", :null => false - t.string "description" - t.integer "position", :default => 1 - t.integer "topics_count", :default => 0, :null => false - t.integer "messages_count", :default => 0, :null => false - t.integer "last_message_id" - t.integer "parent_id" - t.integer "course_id" - t.integer "org_subfield_id" - end - - add_index "boards", ["last_message_id"], :name => "index_boards_on_last_message_id" - add_index "boards", ["project_id"], :name => "boards_project_id" - - create_table "bug_to_osps", :force => true do |t| - t.integer "osp_id" - t.integer "relative_memo_id" - t.string "description" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "changes", :force => true do |t| - t.integer "changeset_id", :null => false - t.string "action", :limit => 1, :default => "", :null => false - t.text "path", :null => false - t.text "from_path" - t.string "from_revision" - t.string "revision" - t.string "branch" - end - - add_index "changes", ["changeset_id"], :name => "changesets_changeset_id" - - create_table "changeset_parents", :id => false, :force => true do |t| - t.integer "changeset_id", :null => false - t.integer "parent_id", :null => false - end - - add_index "changeset_parents", ["changeset_id"], :name => "changeset_parents_changeset_ids" - add_index "changeset_parents", ["parent_id"], :name => "changeset_parents_parent_ids" - - create_table "changesets", :force => true do |t| - t.integer "repository_id", :null => false - t.string "revision", :null => false - t.string "committer" - t.datetime "committed_on", :null => false - t.text "comments" - t.date "commit_date" - t.string "scmid" - t.integer "user_id" - end - - add_index "changesets", ["committed_on"], :name => "index_changesets_on_committed_on" - add_index "changesets", ["repository_id", "revision"], :name => "changesets_repos_rev", :unique => true - add_index "changesets", ["repository_id", "scmid"], :name => "changesets_repos_scmid" - add_index "changesets", ["repository_id"], :name => "index_changesets_on_repository_id" - add_index "changesets", ["user_id"], :name => "index_changesets_on_user_id" - - create_table "changesets_issues", :id => false, :force => true do |t| - t.integer "changeset_id", :null => false - t.integer "issue_id", :null => false - end - - add_index "changesets_issues", ["changeset_id", "issue_id"], :name => "changesets_issues_ids", :unique => true - - create_table "code_review_assignments", :force => true do |t| - t.integer "issue_id" - t.integer "change_id" - t.integer "attachment_id" - t.string "file_path" - t.string "rev" - t.string "rev_to" - t.string "action_type" - t.integer "changeset_id" - end - - create_table "code_review_project_settings", :force => true do |t| - t.integer "project_id" - t.integer "tracker_id" - t.datetime "created_at" - t.datetime "updated_at" - t.integer "updated_by" - t.boolean "hide_code_review_tab", :default => false - t.integer "auto_relation", :default => 1 - t.integer "assignment_tracker_id" - t.text "auto_assign" - t.integer "lock_version", :default => 0, :null => false - t.boolean "tracker_in_review_dialog", :default => false - end - - create_table "code_review_user_settings", :force => true do |t| - t.integer "user_id", :default => 0, :null => false - t.integer "mail_notification", :default => 0, :null => false - t.datetime "created_at" - t.datetime "updated_at" - end - - create_table "code_reviews", :force => true do |t| - t.integer "project_id" - t.integer "change_id" - t.datetime "created_at" - t.datetime "updated_at" - t.integer "line" - t.integer "updated_by_id" - t.integer "lock_version", :default => 0, :null => false - t.integer "status_changed_from" - t.integer "status_changed_to" - t.integer "issue_id" - t.string "action_type" - t.string "file_path" - t.string "rev" - t.string "rev_to" - t.integer "attachment_id" - t.integer "file_count", :default => 0, :null => false - t.boolean "diff_all" - end - - create_table "code_tests", :force => true do |t| - t.integer "homework_id" - t.integer "wait_time", :default => 0 - t.integer "language" - t.integer "status" - t.integer "time_used", :default => 0 - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "student_work_id", :default => 0 - end - - create_table "comments", :force => true do |t| - t.string "commented_type", :limit => 30, :default => "", :null => false - t.integer "commented_id", :default => 0, :null => false - t.integer "author_id", :default => 0, :null => false - t.text "comments" - t.datetime "created_on", :null => false - t.datetime "updated_on", :null => false - t.integer "parent_id" - t.integer "comments_count", :default => 0 - t.integer "reply_id" - end - - add_index "comments", ["author_id"], :name => "index_comments_on_author_id" - add_index "comments", ["commented_id", "commented_type"], :name => "index_comments_on_commented_id_and_commented_type" - - create_table "commits", :force => true do |t| - t.integer "repository_id" - t.string "version" - t.string "committer" - t.text "comments" - t.datetime "committed_on" - t.integer "project_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "contest_notifications", :force => true do |t| - t.text "title" - t.text "content" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "contesting_projects", :force => true do |t| - t.integer "project_id" - t.string "contest_id" - t.integer "user_id" - t.string "description" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.string "reward" - end - - create_table "contesting_softapplications", :force => true do |t| - t.integer "softapplication_id" - t.integer "contest_id" - t.integer "user_id" - t.string "description" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.string "reward" - end - - create_table "contestnotifications", :force => true do |t| - t.integer "contest_id" - t.string "title" - t.string "summary" - t.text "description" - t.integer "author_id" - t.integer "notificationcomments_count" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "contests", :force => true do |t| - t.string "name" - t.string "budget", :default => "" - t.integer "author_id" - t.date "deadline" - t.string "description" - t.integer "commit" - t.string "password" - t.datetime "created_on", :null => false - t.datetime "updated_on", :null => false - end - - create_table "course_activities", :force => true do |t| - t.integer "user_id" - t.integer "course_id" - t.integer "course_act_id" - t.string "course_act_type" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - add_index "course_activities", ["course_id", "course_act_id", "course_act_type", "created_at"], :name => "course_act_index" - - create_table "course_attachments", :force => true do |t| - t.string "filename" - t.string "disk_filename" - t.integer "filesize" - t.string "content_type" - t.string "digest" - t.integer "downloads" - t.string "author_id" - t.string "integer" - t.string "description" - t.string "disk_directory" - t.integer "attachtype" - t.integer "is_public" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "container_id", :default => 0 - end - - create_table "course_contributor_scores", :force => true do |t| - t.integer "course_id" - t.integer "user_id" - t.integer "message_num", :default => 0 - t.integer "message_reply_num", :default => 0 - t.integer "news_reply_num", :default => 0 - t.integer "resource_num", :default => 0 - t.integer "journal_num", :default => 0 - t.integer "journal_reply_num", :default => 0 - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "total_score", :default => 0 - t.integer "homework_journal_num", :default => 0 - t.integer "news_num", :default => 0 - end - - create_table "course_groups", :force => true do |t| - t.string "name" - t.integer "course_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "course_infos", :force => true do |t| - t.integer "course_id" - t.integer "user_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "course_messages", :force => true do |t| - t.integer "user_id" - t.integer "course_id" - t.integer "course_message_id" - t.string "course_message_type" - t.integer "viewed" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.text "content" - t.integer "status" - t.integer "apply_user_id" - t.integer "apply_result" - end - - add_index "course_messages", ["course_message_type"], :name => "index_course_messages_on_course_message_type" - add_index "course_messages", ["user_id", "course_id", "created_at"], :name => "index_course_messages_on_user_id_and_course_id_and_created_at" - - create_table "course_statuses", :force => true do |t| - t.integer "changesets_count" - t.integer "watchers_count" - t.integer "course_id" - t.float "grade", :default => 0.0 - t.integer "course_ac_para", :default => 0 - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "courses", :force => true do |t| - t.integer "tea_id" - t.string "name" - t.integer "state" - t.string "code" - t.integer "time" - t.string "extra" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.string "location" - t.string "term" - t.string "string" - t.string "password" - t.string "setup_time" - t.string "endup_time" - t.string "class_period" - t.integer "school_id" - t.text "description" - t.integer "status", :default => 1 - t.integer "attachmenttype", :default => 2 - t.integer "lft" - t.integer "rgt" - t.integer "is_public", :limit => 1, :default => 1 - t.integer "inherit_members", :limit => 1, :default => 1 - t.integer "open_student", :default => 0 - t.integer "outline", :default => 0 - t.integer "publish_resource", :default => 0 - t.integer "is_delete", :default => 0 - t.integer "end_time" - t.string "end_term" - t.integer "is_excellent", :default => 0 - t.integer "excellent_option", :default => 0 - t.integer "is_copy", :default => 0 - t.integer "visits", :default => 0 - t.integer "syllabus_id" - t.string "invite_code" - t.string "qrcode" - end - - add_index "courses", ["invite_code"], :name => "index_courses_on_invite_code", :unique => true - add_index "courses", ["syllabus_id"], :name => "index_courses_on_syllabus_id" - - create_table "custom_fields", :force => true do |t| - t.string "type", :limit => 30, :default => "", :null => false - t.string "name", :limit => 30, :default => "", :null => false - t.string "field_format", :limit => 30, :default => "", :null => false - t.text "possible_values" - t.string "regexp", :default => "" - t.integer "min_length", :default => 0, :null => false - t.integer "max_length", :default => 0, :null => false - t.boolean "is_required", :default => false, :null => false - t.boolean "is_for_all", :default => false, :null => false - t.boolean "is_filter", :default => false, :null => false - t.integer "position", :default => 1 - t.boolean "searchable", :default => false - t.text "default_value" - t.boolean "editable", :default => true - t.boolean "visible", :default => true, :null => false - t.boolean "multiple", :default => false - end - - add_index "custom_fields", ["id", "type"], :name => "index_custom_fields_on_id_and_type" - - create_table "custom_fields_projects", :id => false, :force => true do |t| - t.integer "custom_field_id", :default => 0, :null => false - t.integer "project_id", :default => 0, :null => false - end - - add_index "custom_fields_projects", ["custom_field_id", "project_id"], :name => "index_custom_fields_projects_on_custom_field_id_and_project_id", :unique => true - - create_table "custom_fields_trackers", :id => false, :force => true do |t| - t.integer "custom_field_id", :default => 0, :null => false - t.integer "tracker_id", :default => 0, :null => false - end - - add_index "custom_fields_trackers", ["custom_field_id", "tracker_id"], :name => "index_custom_fields_trackers_on_custom_field_id_and_tracker_id", :unique => true - - create_table "custom_values", :force => true do |t| - t.string "customized_type", :limit => 30, :default => "", :null => false - t.integer "customized_id", :default => 0, :null => false - t.integer "custom_field_id", :default => 0, :null => false - t.text "value" - end - - add_index "custom_values", ["custom_field_id"], :name => "index_custom_values_on_custom_field_id" - add_index "custom_values", ["customized_type", "customized_id"], :name => "custom_values_customized" - - create_table "delayed_jobs", :force => true do |t| - t.integer "priority", :default => 0, :null => false - t.integer "attempts", :default => 0, :null => false - t.text "handler", :null => false - t.text "last_error" - t.datetime "run_at" - t.datetime "locked_at" - t.datetime "failed_at" - t.string "locked_by" - t.string "queue" - t.datetime "created_at" - t.datetime "updated_at" - end - - add_index "delayed_jobs", ["priority", "run_at"], :name => "delayed_jobs_priority" - - create_table "discuss_demos", :force => true do |t| - t.string "title" - t.text "body" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "documents", :force => true do |t| - t.integer "project_id", :default => 0, :null => false - t.integer "category_id", :default => 0, :null => false - t.string "title", :limit => 60, :default => "", :null => false - t.text "description" - t.datetime "created_on" - t.integer "user_id", :default => 0 - t.integer "is_public", :default => 1 - end - - add_index "documents", ["category_id"], :name => "index_documents_on_category_id" - add_index "documents", ["created_on"], :name => "index_documents_on_created_on" - add_index "documents", ["project_id"], :name => "documents_project_id" - - create_table "dts", :primary_key => "Num", :force => true do |t| - t.string "Defect", :limit => 50 - t.string "Category", :limit => 50 - t.string "File" - t.string "Method" - t.string "Module", :limit => 20 - t.string "Variable", :limit => 50 - t.integer "StartLine" - t.integer "IPLine" - t.string "IPLineCode", :limit => 200 - t.string "Judge", :limit => 15 - t.integer "Review", :limit => 1 - t.string "Description" - t.text "PreConditions", :limit => 2147483647 - t.text "TraceInfo", :limit => 2147483647 - t.text "Code", :limit => 2147483647 - t.integer "project_id" - t.datetime "created_at" - t.datetime "updated_at" - t.integer "id", :null => false - end - - create_table "editor_of_documents", :force => true do |t| - t.integer "editor_id" - t.integer "org_document_comment_id" - t.datetime "created_at" - end - - create_table "enabled_modules", :force => true do |t| - t.integer "project_id" - t.string "name", :null => false - t.integer "course_id" - end - - add_index "enabled_modules", ["project_id"], :name => "enabled_modules_project_id" - - create_table "enumerations", :force => true do |t| - t.string "name", :limit => 30, :default => "", :null => false - t.integer "position", :default => 1 - t.boolean "is_default", :default => false, :null => false - t.string "type" - t.boolean "active", :default => true, :null => false - t.integer "project_id" - t.integer "parent_id" - t.string "position_name", :limit => 30 - end - - add_index "enumerations", ["id", "type"], :name => "index_enumerations_on_id_and_type" - add_index "enumerations", ["project_id"], :name => "index_enumerations_on_project_id" - - create_table "exercise_answers", :force => true do |t| - t.integer "user_id" - t.integer "exercise_question_id" - t.integer "exercise_choice_id" - t.text "answer_text" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "exercise_choices", :force => true do |t| - t.integer "exercise_question_id" - t.text "choice_text" - t.integer "choice_position" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "exercise_questions", :force => true do |t| - t.text "question_title" - t.integer "question_type" - t.integer "question_number" - t.integer "exercise_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "question_score" - end - - create_table "exercise_standard_answers", :force => true do |t| - t.integer "exercise_question_id" - t.integer "exercise_choice_id" - t.text "answer_text" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "exercise_users", :force => true do |t| - t.integer "user_id" - t.integer "exercise_id" - t.integer "score" - t.datetime "start_at" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.datetime "end_at" - t.integer "status" - end - - create_table "exercises", :force => true do |t| - t.text "exercise_name" - t.text "exercise_description" - t.integer "course_id" - t.integer "exercise_status" - t.integer "user_id" - t.integer "time" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.datetime "publish_time" - t.datetime "end_time" - t.integer "show_result" - end - - create_table "first_pages", :force => true do |t| - t.string "web_title" - t.string "title" - t.text "description" - t.string "page_type" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "sort_type" - t.integer "image_width", :default => 107 - t.integer "image_height", :default => 63 - t.integer "show_course", :default => 1 - t.integer "show_contest", :default => 1 - end - - create_table "forge_activities", :force => true do |t| - t.integer "user_id" - t.integer "project_id" - t.integer "forge_act_id" - t.string "forge_act_type" - t.integer "org_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - add_index "forge_activities", ["forge_act_id"], :name => "index_forge_activities_on_forge_act_id" - add_index "forge_activities", ["project_id", "forge_act_id", "created_at", "forge_act_type"], :name => "forge_act_index" - - create_table "forge_messages", :force => true do |t| - t.integer "user_id" - t.integer "project_id" - t.integer "forge_message_id" - t.string "forge_message_type" - t.integer "viewed" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.string "secret_key" - t.integer "status" - end - - add_index "forge_messages", ["forge_message_id", "forge_message_type"], :name => "index_forge_messages_on_forge_message_id_and_forge_message_type" - add_index "forge_messages", ["user_id", "project_id", "created_at"], :name => "index_forge_messages_on_user_id_and_project_id_and_created_at" - - create_table "forums", :force => true do |t| - t.string "name", :null => false - t.text "description" - t.integer "topic_count", :default => 0 - t.integer "memo_count", :default => 0 - t.integer "last_memo_id", :default => 0 - t.integer "creator_id", :null => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "sticky" - t.integer "locked" - end - - create_table "forwards", :force => true do |t| - t.integer "from_id" - t.string "from_type" - t.integer "to_id" - t.string "to_type" - t.datetime "created_at" - end - - create_table "groups_users", :id => false, :force => true do |t| - t.integer "group_id", :null => false - t.integer "user_id", :null => false - end - - add_index "groups_users", ["group_id", "user_id"], :name => "groups_users_ids", :unique => true - - create_table "homework_attaches", :force => true do |t| - t.integer "bid_id" - t.integer "user_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.string "reward" - t.string "name" - t.text "description" - t.integer "state" - t.integer "project_id", :default => 0 - t.float "score", :default => 0.0 - t.integer "is_teacher_score", :default => 0 - end - - add_index "homework_attaches", ["bid_id"], :name => "index_homework_attaches_on_bid_id" - - create_table "homework_commons", :force => true do |t| - t.string "name" - t.integer "user_id" - t.text "description" - t.date "publish_time" - t.date "end_time" - t.integer "homework_type", :default => 1 - t.string "late_penalty" - t.integer "course_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "teacher_priority", :default => 1 - t.integer "anonymous_comment", :default => 0 - t.integer "quotes", :default => 0 - t.integer "is_open", :default => 0 - t.datetime "simi_time" - end - - add_index "homework_commons", ["course_id", "id"], :name => "index_homework_commons_on_course_id_and_id" - - create_table "homework_detail_groups", :force => true do |t| - t.integer "homework_common_id" - t.integer "min_num" - t.integer "max_num" - t.integer "base_on_project" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - add_index "homework_detail_groups", ["homework_common_id"], :name => "index_homework_detail_groups_on_homework_common_id" - - create_table "homework_detail_manuals", :force => true do |t| - t.float "ta_proportion" - t.integer "comment_status" - t.date "evaluation_start" - t.date "evaluation_end" - t.integer "evaluation_num" - t.integer "absence_penalty", :default => 1 - t.integer "homework_common_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "homework_detail_programings", :force => true do |t| - t.string "language" - t.text "standard_code", :limit => 2147483647 - t.integer "homework_common_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.float "ta_proportion", :default => 0.1 - t.integer "question_id" - end - - create_table "homework_evaluations", :force => true do |t| - t.string "user_id" - t.string "homework_attach_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "homework_for_courses", :force => true do |t| - t.integer "course_id" - t.integer "bid_id" - end - - add_index "homework_for_courses", ["bid_id"], :name => "index_homework_for_courses_on_bid_id" - add_index "homework_for_courses", ["course_id"], :name => "index_homework_for_courses_on_course_id" - - create_table "homework_tests", :force => true do |t| - t.text "input" - t.text "output" - t.integer "homework_common_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "result" - t.text "error_msg" - end - - create_table "homework_users", :force => true do |t| - t.string "homework_attach_id" - t.string "user_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "invite_lists", :force => true do |t| - t.integer "project_id" - t.integer "user_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.string "mail" - end - - create_table "issue_categories", :force => true do |t| - t.integer "project_id", :default => 0, :null => false - t.string "name", :limit => 30, :default => "", :null => false - t.integer "assigned_to_id" - end - - add_index "issue_categories", ["assigned_to_id"], :name => "index_issue_categories_on_assigned_to_id" - add_index "issue_categories", ["project_id"], :name => "issue_categories_project_id" - - create_table "issue_relations", :force => true do |t| - t.integer "issue_from_id", :null => false - t.integer "issue_to_id", :null => false - t.string "relation_type", :default => "", :null => false - t.integer "delay" - end - - add_index "issue_relations", ["issue_from_id", "issue_to_id"], :name => "index_issue_relations_on_issue_from_id_and_issue_to_id", :unique => true - add_index "issue_relations", ["issue_from_id"], :name => "index_issue_relations_on_issue_from_id" - add_index "issue_relations", ["issue_to_id"], :name => "index_issue_relations_on_issue_to_id" - - create_table "issue_statuses", :force => true do |t| - t.string "name", :limit => 30, :default => "", :null => false - t.boolean "is_closed", :default => false, :null => false - t.boolean "is_default", :default => false, :null => false - t.integer "position", :default => 1 - t.integer "default_done_ratio" - end - - add_index "issue_statuses", ["is_closed"], :name => "index_issue_statuses_on_is_closed" - add_index "issue_statuses", ["is_default"], :name => "index_issue_statuses_on_is_default" - add_index "issue_statuses", ["position"], :name => "index_issue_statuses_on_position" - - create_table "issues", :force => true do |t| - t.integer "tracker_id", :null => false - t.integer "project_id", :null => false - t.string "subject", :default => "", :null => false - t.text "description" - t.date "due_date" - t.integer "category_id" - t.integer "status_id", :null => false - t.integer "assigned_to_id" - t.integer "priority_id", :null => false - t.integer "fixed_version_id" - t.integer "author_id", :null => false - t.integer "lock_version", :default => 0, :null => false - t.datetime "created_on" - t.datetime "updated_on" - t.date "start_date" - t.integer "done_ratio", :default => 0, :null => false - t.float "estimated_hours" - t.integer "parent_id" - t.integer "root_id" - t.integer "lft" - t.integer "rgt" - t.boolean "is_private", :default => false, :null => false - t.datetime "closed_on" - t.integer "project_issues_index" - end - - add_index "issues", ["assigned_to_id"], :name => "index_issues_on_assigned_to_id" - add_index "issues", ["author_id"], :name => "index_issues_on_author_id" - add_index "issues", ["category_id"], :name => "index_issues_on_category_id" - add_index "issues", ["created_on"], :name => "index_issues_on_created_on" - add_index "issues", ["fixed_version_id"], :name => "index_issues_on_fixed_version_id" - add_index "issues", ["priority_id"], :name => "index_issues_on_priority_id" - add_index "issues", ["project_id"], :name => "issues_project_id" - add_index "issues", ["root_id", "lft", "rgt"], :name => "index_issues_on_root_id_and_lft_and_rgt" - add_index "issues", ["status_id"], :name => "index_issues_on_status_id" - add_index "issues", ["tracker_id"], :name => "index_issues_on_tracker_id" - - create_table "join_in_competitions", :force => true do |t| - t.integer "user_id" - t.integer "competition_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "join_in_contests", :force => true do |t| - t.integer "user_id" - t.integer "bid_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "journal_details", :force => true do |t| - t.integer "journal_id", :default => 0, :null => false - t.string "property", :limit => 30, :default => "", :null => false - t.string "prop_key", :limit => 30, :default => "", :null => false - t.text "old_value" - t.text "value" - end - - add_index "journal_details", ["journal_id"], :name => "journal_details_journal_id" - - create_table "journal_replies", :id => false, :force => true do |t| - t.integer "journal_id" - t.integer "user_id" - t.integer "reply_id" - end - - add_index "journal_replies", ["journal_id"], :name => "index_journal_replies_on_journal_id" - add_index "journal_replies", ["reply_id"], :name => "index_journal_replies_on_reply_id" - add_index "journal_replies", ["user_id"], :name => "index_journal_replies_on_user_id" - - create_table "journals", :force => true do |t| - t.integer "journalized_id", :default => 0, :null => false - t.string "journalized_type", :limit => 30, :default => "", :null => false - t.integer "user_id", :default => 0, :null => false - t.text "notes" - t.datetime "created_on", :null => false - t.boolean "private_notes", :default => false, :null => false - t.integer "parent_id" - t.integer "comments_count", :default => 0 - t.integer "reply_id" - end - - add_index "journals", ["created_on"], :name => "index_journals_on_created_on" - add_index "journals", ["journalized_id", "journalized_type"], :name => "journals_journalized_id" - add_index "journals", ["journalized_id"], :name => "index_journals_on_journalized_id" - add_index "journals", ["user_id"], :name => "index_journals_on_user_id" - - create_table "journals_for_messages", :force => true do |t| - t.integer "jour_id" - t.string "jour_type" - t.integer "user_id" - t.text "notes" - t.integer "status" - t.integer "reply_id" - t.datetime "created_on", :null => false - t.datetime "updated_on", :null => false - t.string "m_parent_id" - t.boolean "is_readed" - t.integer "m_reply_count" - t.integer "m_reply_id" - t.integer "is_comprehensive_evaluation" - t.integer "private", :default => 0 - end - - create_table "kindeditor_assets", :force => true do |t| - t.string "asset" - t.integer "file_size" - t.string "file_type" - t.integer "owner_id" - t.string "asset_type" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "owner_type", :default => 0 - end - - create_table "member_roles", :force => true do |t| - t.integer "member_id", :null => false - t.integer "role_id", :null => false - t.integer "inherited_from" - end - - add_index "member_roles", ["member_id"], :name => "index_member_roles_on_member_id" - add_index "member_roles", ["role_id"], :name => "index_member_roles_on_role_id" - - create_table "members", :force => true do |t| - t.integer "user_id", :default => 0, :null => false - t.integer "project_id", :default => 0 - t.datetime "created_on" - t.boolean "mail_notification", :default => false, :null => false - t.integer "course_id", :default => -1 - t.integer "course_group_id", :default => 0 - end - - add_index "members", ["project_id"], :name => "index_members_on_project_id" - add_index "members", ["user_id", "project_id", "course_id"], :name => "index_members_on_user_id_and_project_id", :unique => true - add_index "members", ["user_id"], :name => "index_members_on_user_id" - - create_table "memo_messages", :force => true do |t| - t.integer "user_id" - t.integer "forum_id" - t.integer "memo_id" - t.string "memo_type" - t.integer "viewed" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - add_index "memo_messages", ["memo_id", "memo_type"], :name => "index_memo_messages_on_memo_id_and_memo_type" - add_index "memo_messages", ["user_id", "forum_id", "created_at"], :name => "index_memo_messages_on_user_id_and_forum_id_and_created_at" - - create_table "memos", :force => true do |t| - t.integer "forum_id", :null => false - t.integer "parent_id" - t.string "subject", :null => false - t.text "content", :null => false - t.integer "author_id", :null => false - t.integer "replies_count", :default => 0 - t.integer "last_reply_id" - t.boolean "lock", :default => false - t.boolean "sticky", :default => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "viewed_count", :default => 0 - end - - create_table "message_alls", :force => true do |t| - t.integer "user_id" - t.integer "message_id" - t.string "message_type" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - add_index "message_alls", ["message_type"], :name => "index_message_alls_on_message_type" - add_index "message_alls", ["user_id", "message_id", "created_at"], :name => "index_message_alls_on_user_id_and_message_id_and_created_at" - - create_table "messages", :force => true do |t| - t.integer "board_id", :null => false - t.integer "parent_id" - t.string "subject", :default => "", :null => false - t.text "content" - t.integer "author_id" - t.integer "replies_count", :default => 0, :null => false - t.integer "last_reply_id" - t.datetime "created_on", :null => false - t.datetime "updated_on", :null => false - t.boolean "locked", :default => false - t.integer "sticky", :default => 0 - t.integer "reply_id" - t.integer "quotes" - t.integer "status", :default => 0 - end - - add_index "messages", ["author_id"], :name => "index_messages_on_author_id" - add_index "messages", ["board_id"], :name => "messages_board_id" - add_index "messages", ["created_on"], :name => "index_messages_on_created_on" - add_index "messages", ["last_reply_id"], :name => "index_messages_on_last_reply_id" - add_index "messages", ["parent_id"], :name => "messages_parent_id" - - create_table "news", :force => true do |t| - t.integer "project_id" - t.string "title", :limit => 60, :default => "", :null => false - t.string "summary", :default => "" - t.text "description" - t.integer "author_id", :default => 0, :null => false - t.datetime "created_on" - t.integer "comments_count", :default => 0, :null => false - t.integer "course_id" - t.integer "sticky", :default => 0 - t.integer "org_subfield_id" - end - - add_index "news", ["author_id"], :name => "index_news_on_author_id" - add_index "news", ["created_on"], :name => "index_news_on_created_on" - add_index "news", ["project_id"], :name => "news_project_id" - - create_table "no_uses", :force => true do |t| - t.integer "user_id", :null => false - t.string "no_use_type" - t.integer "no_use_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "notificationcomments", :force => true do |t| - t.string "notificationcommented_type" - t.integer "notificationcommented_id" - t.integer "author_id" - t.text "notificationcomments" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "onclick_times", :force => true do |t| - t.integer "user_id" - t.datetime "onclick_time" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "open_id_authentication_associations", :force => true do |t| - t.integer "issued" - t.integer "lifetime" - t.string "handle" - t.string "assoc_type" - t.binary "server_url" - t.binary "secret" - end - - create_table "open_id_authentication_nonces", :force => true do |t| - t.integer "timestamp", :null => false - t.string "server_url" - t.string "salt", :null => false - end - - create_table "open_source_projects", :force => true do |t| - t.string "name" - t.text "description" - t.integer "commit_count", :default => 0 - t.integer "code_line", :default => 0 - t.integer "users_count", :default => 0 - t.date "last_commit_time" - t.string "url" - t.date "date_collected" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "option_numbers", :force => true do |t| - t.integer "user_id" - t.integer "memo" - t.integer "messages_for_issues" - t.integer "issues_status" - t.integer "replay_for_message" - t.integer "replay_for_memo" - t.integer "follow" - t.integer "tread" - t.integer "praise_by_one" - t.integer "praise_by_two" - t.integer "praise_by_three" - t.integer "tread_by_one" - t.integer "tread_by_two" - t.integer "tread_by_three" - t.integer "changeset" - t.integer "document" - t.integer "attachment" - t.integer "issue_done_ratio" - t.integer "post_issue" - t.integer "score_type" - t.integer "total_score" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "project_id" - end - - create_table "org_activities", :force => true do |t| - t.integer "user_id" - t.integer "org_act_id" - t.string "org_act_type" - t.integer "container_id" - t.string "container_type" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "org_courses", :force => true do |t| - t.integer "organization_id" - t.integer "course_id" - t.datetime "created_at" - end - - create_table "org_document_comments", :force => true do |t| - t.text "title" - t.text "content" - t.integer "organization_id" - t.integer "creator_id" - t.integer "parent_id" - t.integer "reply_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.boolean "locked", :default => false - t.integer "sticky", :default => 0 - t.integer "org_subfield_id" - t.integer "status", :default => 0 - end - - create_table "org_member_roles", :force => true do |t| - t.integer "org_member_id" - t.integer "role_id" - end - - create_table "org_members", :force => true do |t| - t.integer "user_id" - t.integer "organization_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "org_messages", :force => true do |t| - t.integer "user_id" - t.integer "sender_id" - t.integer "organization_id" - t.string "message_type" - t.integer "message_id" - t.integer "viewed" - t.string "content" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "status", :default => 0 - end - - create_table "org_projects", :force => true do |t| - t.integer "organization_id" - t.integer "project_id" - t.datetime "created_at" - end - - create_table "org_subfield_messages", :force => true do |t| - t.integer "org_subfield_id" - t.integer "message_id" - t.string "message_type" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "org_subfields", :force => true do |t| - t.integer "organization_id" - t.integer "priority" - t.string "name" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.string "field_type" - t.integer "hide", :default => 0 - t.integer "status", :default => 1 - end - - create_table "organizations", :force => true do |t| - t.string "name" - t.text "description" - t.integer "creator_id" - t.integer "home_id" - t.boolean "is_public" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.boolean "allow_guest_download", :default => true - t.integer "visits", :default => 0 - t.integer "show_mode", :default => 0 - t.integer "allow_teacher", :default => 0 - end - - create_table "phone_app_versions", :force => true do |t| - t.string "version" - t.text "description" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "poll_answers", :force => true do |t| - t.integer "poll_question_id" - t.text "answer_text" - t.integer "answer_position" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "poll_questions", :force => true do |t| - t.string "question_title" - t.integer "question_type" - t.integer "is_necessary" - t.integer "poll_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "question_number" - end - - create_table "poll_users", :force => true do |t| - t.integer "user_id" - t.integer "poll_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "poll_votes", :force => true do |t| - t.integer "user_id" - t.integer "poll_question_id" - t.integer "poll_answer_id" - t.text "vote_text" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "polls", :force => true do |t| - t.string "polls_name" - t.string "polls_type" - t.integer "polls_group_id" - t.integer "polls_status" - t.integer "user_id" - t.datetime "published_at" - t.datetime "closed_at" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.text "polls_description" - t.integer "show_result", :default => 1 - end - - create_table "praise_tread_caches", :force => true do |t| - t.integer "object_id", :null => false - t.string "object_type" - t.integer "praise_num" - t.integer "tread_num" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "praise_treads", :force => true do |t| - t.integer "user_id", :null => false - t.integer "praise_tread_object_id" - t.string "praise_tread_object_type" - t.integer "praise_or_tread" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "principal_activities", :force => true do |t| - t.integer "user_id" - t.integer "principal_id" - t.integer "principal_act_id" - t.string "principal_act_type" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "project_infos", :force => true do |t| - t.integer "project_id" - t.integer "user_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "project_scores", :force => true do |t| - t.string "project_id" - t.integer "score" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "issue_num", :default => 0 - t.integer "issue_journal_num", :default => 0 - t.integer "news_num", :default => 0 - t.integer "documents_num", :default => 0 - t.integer "changeset_num", :default => 0 - t.integer "board_message_num", :default => 0 - t.integer "board_num", :default => 0 - t.integer "attach_num", :default => 0 - t.datetime "commit_time" - end - - create_table "project_statuses", :force => true do |t| - t.integer "changesets_count" - t.integer "watchers_count" - t.integer "project_id" - t.integer "project_type" - t.float "grade", :default => 0.0 - t.integer "course_ac_para", :default => 0 - end - - add_index "project_statuses", ["grade"], :name => "index_project_statuses_on_grade" - - create_table "projecting_softapplictions", :force => true do |t| - t.integer "user_id" - t.integer "softapplication_id" - t.integer "project_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "projects", :force => true do |t| - t.string "name", :default => "", :null => false - t.text "description" - t.string "homepage", :default => "" - t.boolean "is_public", :default => true, :null => false - t.integer "parent_id" - t.datetime "created_on" - t.datetime "updated_on" - t.string "identifier" - t.integer "status", :default => 1, :null => false - t.integer "lft" - t.integer "rgt" - t.boolean "inherit_members", :default => false, :null => false - t.integer "project_type" - t.boolean "hidden_repo", :default => false, :null => false - t.integer "attachmenttype", :default => 1 - t.integer "user_id" - t.integer "dts_test", :default => 0 - t.string "enterprise_name" - t.integer "organization_id" - t.integer "project_new_type" - t.integer "gpid" - t.integer "forked_from_project_id" - t.integer "forked_count" - t.integer "commits_count", :default => 0 - t.integer "publish_resource", :default => 0 - t.integer "issues_count", :default => 0 - t.integer "attachments_count", :default => 0 - t.integer "boards_count", :default => 0 - t.integer "news_count", :default => 0 - t.integer "acts_count", :default => 0 - t.integer "journals_count", :default => 0 - t.integer "boards_reply_count", :default => 0 - t.integer "visits", :default => 0 - t.integer "hot", :default => 0 - end - - add_index "projects", ["lft"], :name => "index_projects_on_lft" - add_index "projects", ["rgt"], :name => "index_projects_on_rgt" - - create_table "projects_trackers", :id => false, :force => true do |t| - t.integer "project_id", :default => 0, :null => false - t.integer "tracker_id", :default => 0, :null => false - end - - add_index "projects_trackers", ["project_id", "tracker_id"], :name => "projects_trackers_unique", :unique => true - add_index "projects_trackers", ["project_id"], :name => "projects_trackers_project_id" - - create_table "quality_analyses", :force => true do |t| - t.integer "project_id" - t.string "author_login" - t.string "rep_identifier" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "sonar_version", :default => 0 - t.string "path" - t.string "branch" - t.string "language" - t.string "sonar_name" - end - - create_table "queries", :force => true do |t| - t.integer "project_id" - t.string "name", :default => "", :null => false - t.text "filters" - t.integer "user_id", :default => 0, :null => false - t.boolean "is_public", :default => false, :null => false - t.text "column_names" - t.text "sort_criteria" - t.string "group_by" - t.string "type" - end - - add_index "queries", ["project_id"], :name => "index_queries_on_project_id" - add_index "queries", ["user_id"], :name => "index_queries_on_user_id" - - create_table "relative_memo_to_open_source_projects", :force => true do |t| - t.integer "osp_id" - t.integer "relative_memo_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "relative_memos", :force => true do |t| - t.integer "osp_id" - t.integer "parent_id" - t.string "subject", :null => false - t.text "content", :limit => 16777215, :null => false - t.integer "author_id" - t.integer "replies_count", :default => 0 - t.integer "last_reply_id" - t.boolean "lock", :default => false - t.boolean "sticky", :default => false - t.boolean "is_quote", :default => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "viewed_count_crawl", :default => 0 - t.integer "viewed_count_local", :default => 0 - t.string "url" - t.string "username" - t.string "userhomeurl" - t.date "date_collected" - t.string "topic_resource" - end - - create_table "rep_statics", :force => true do |t| - t.integer "project_id" - t.integer "commits_num" - t.string "uname" - t.string "email" - t.integer "add" - t.integer "del" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "changeset" - end - - create_table "repositories", :force => true do |t| - t.integer "project_id", :default => 0, :null => false - t.string "url", :default => "", :null => false - t.string "login", :limit => 60, :default => "" - t.string "password", :default => "" - t.string "root_url", :default => "" - t.string "type" - t.string "path_encoding", :limit => 64 - t.string "log_encoding", :limit => 64 - t.text "extra_info" - t.string "identifier" - t.boolean "is_default", :default => false - t.boolean "hidden", :default => false - end - - add_index "repositories", ["project_id"], :name => "index_repositories_on_project_id" - - create_table "rich_rich_files", :force => true do |t| - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.string "rich_file_file_name" - t.string "rich_file_content_type" - t.integer "rich_file_file_size" - t.datetime "rich_file_updated_at" - t.string "owner_type" - t.integer "owner_id" - t.text "uri_cache" - t.string "simplified_type", :default => "file" - end - - create_table "roles", :force => true do |t| - t.string "name", :limit => 30, :default => "", :null => false - t.integer "position", :default => 1 - t.boolean "assignable", :default => true - t.integer "builtin", :default => 0, :null => false - t.text "permissions" - t.string "issues_visibility", :limit => 30, :default => "default", :null => false - end - - create_table "schools", :force => true do |t| - t.string "name" - t.string "province" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.string "logo_link" - t.string "pinyin" - t.integer "school_type", :default => 0 - end - - create_table "secdomains", :force => true do |t| - t.integer "sub_type" - t.string "subname" - t.integer "pid", :default => 0 - t.string "desc" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "seems_rateable_cached_ratings", :force => true do |t| - t.integer "cacheable_id", :limit => 8 - t.string "cacheable_type" - t.float "avg", :null => false - t.integer "cnt", :null => false - t.string "dimension" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "seems_rateable_rates", :force => true do |t| - t.integer "rater_id", :limit => 8 - t.integer "rateable_id" - t.string "rateable_type" - t.float "stars", :null => false - t.string "dimension" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "is_teacher_score", :default => 0 - end - - create_table "settings", :force => true do |t| - t.string "name", :default => "", :null => false - t.text "value" - t.datetime "updated_on" - end - - add_index "settings", ["name"], :name => "index_settings_on_name" - - create_table "shares", :force => true do |t| - t.date "created_on" - t.string "url" - t.string "title" - t.integer "share_type" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "project_id" - t.integer "user_id" - t.string "description" - end - - create_table "shield_activities", :force => true do |t| - t.string "container_type" - t.integer "container_id" - t.string "shield_type" - t.integer "shield_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "shield_wechat_messages", :force => true do |t| - t.integer "container_id" - t.string "container_type" - t.integer "shield_id" - t.string "shield_type" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "softapplications", :force => true do |t| - t.string "name" - t.text "description" - t.integer "app_type_id" - t.string "app_type_name" - t.string "android_min_version_available" - t.integer "user_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "contest_id" - t.integer "softapplication_id" - t.integer "is_public" - t.string "application_developers" - t.string "deposit_project_url" - t.string "deposit_project" - t.integer "project_id" - end - - create_table "sonar_errors", :force => true do |t| - t.integer "project_id" - t.string "jenkins_job_name" - t.text "output" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "ssos", :force => true do |t| - t.integer "user_id" - t.string "openid" - t.string "name" - t.string "password" - t.string "email" - t.integer "sex" - t.string "school" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - add_index "ssos", ["user_id"], :name => "index_ssos_on_user_id" - - create_table "student_work_projects", :force => true do |t| - t.integer "homework_common_id" - t.integer "student_work_id" - t.integer "project_id" - t.integer "user_id" - t.integer "is_leader" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - add_index "student_work_projects", ["homework_common_id"], :name => "index_student_work_projects_on_homework_common_id" - add_index "student_work_projects", ["project_id"], :name => "index_student_work_projects_on_project_id" - add_index "student_work_projects", ["student_work_id"], :name => "index_student_work_projects_on_student_work_id" - add_index "student_work_projects", ["user_id"], :name => "index_student_work_projects_on_user_id" - - create_table "student_work_tests", :force => true do |t| - t.integer "student_work_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "status", :default => 9 - t.text "results" - t.text "src" - end - - create_table "student_works", :force => true do |t| - t.string "name" - t.text "description", :limit => 2147483647 - t.integer "homework_common_id" - t.integer "user_id" - t.float "final_score" - t.float "teacher_score" - t.float "student_score" - t.float "teaching_asistant_score" - t.integer "project_id", :default => 0 - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "late_penalty", :default => 0 - t.integer "absence_penalty", :default => 0 - t.float "system_score", :default => 0.0 - t.boolean "is_test", :default => false - t.integer "simi_id" - t.integer "simi_value" - t.float "work_score" - t.integer "work_status", :default => 0 - end - - add_index "student_works", ["homework_common_id", "user_id"], :name => "index_student_works_on_homework_common_id_and_user_id" - - create_table "student_works_evaluation_distributions", :force => true do |t| - t.integer "student_work_id" - t.integer "user_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "student_works_scores", :force => true do |t| - t.integer "student_work_id" - t.integer "user_id" - t.integer "score" - t.text "comment" - t.integer "reviewer_role" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "students_for_courses", :force => true do |t| - t.integer "student_id" - t.integer "course_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - add_index "students_for_courses", ["course_id"], :name => "index_students_for_courses_on_course_id" - add_index "students_for_courses", ["student_id"], :name => "index_students_for_courses_on_student_id" - - create_table "sub_document_comments", :force => true do |t| - t.text "content" - t.text "title" - t.integer "sub_domain_id" - t.integer "creator_id" - t.integer "parent_id" - t.integer "reply_id" - t.integer "locked" - t.integer "sticky" - t.integer "org_subfield_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "sub_domains", :force => true do |t| - t.integer "org_subfield_id" - t.integer "priority", :default => 0 - t.string "name" - t.string "field_type" - t.integer "hide", :default => 0 - t.integer "status", :default => 0 - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "subfield_subdomain_dirs", :force => true do |t| - t.integer "org_subfield_id" - t.string "name" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "syllabuses", :force => true do |t| - t.string "title" - t.text "description" - t.integer "user_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.string "eng_name" - t.integer "syllabus_type" - t.integer "credit" - t.integer "hours" - t.integer "theory_hours" - t.integer "practice_hours" - t.string "applicable_major" - t.string "pre_course" - t.integer "visits", :default => 0 - t.integer "des_status", :default => 0 - end - - add_index "syllabuses", ["user_id"], :name => "index_syllabuses_on_user_id" - - create_table "system_messages", :force => true do |t| - t.integer "user_id" - t.string "content" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.text "description" - t.string "subject" - end - - create_table "taggings", :force => true do |t| - t.integer "tag_id" - t.integer "taggable_id" - t.string "taggable_type" - t.integer "tagger_id" - t.string "tagger_type" - t.string "context", :limit => 128 - t.datetime "created_at" - end - - add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id" - add_index "taggings", ["taggable_id", "taggable_type", "context"], :name => "index_taggings_on_taggable_id_and_taggable_type_and_context" - add_index "taggings", ["taggable_type"], :name => "index_taggings_on_taggable_type" - - create_table "tags", :force => true do |t| - t.string "name" - end - - create_table "teachers", :force => true do |t| - t.string "tea_name" - t.string "location" - t.integer "couurse_time" - t.integer "course_code" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.string "extra" - end - - create_table "time_entries", :force => true do |t| - t.integer "project_id", :null => false - t.integer "user_id", :null => false - t.integer "issue_id" - t.float "hours", :null => false - t.string "comments" - t.integer "activity_id", :null => false - t.date "spent_on", :null => false - t.integer "tyear", :null => false - t.integer "tmonth", :null => false - t.integer "tweek", :null => false - t.datetime "created_on", :null => false - t.datetime "updated_on", :null => false - end - - add_index "time_entries", ["activity_id"], :name => "index_time_entries_on_activity_id" - add_index "time_entries", ["created_on"], :name => "index_time_entries_on_created_on" - add_index "time_entries", ["issue_id"], :name => "time_entries_issue_id" - add_index "time_entries", ["project_id"], :name => "time_entries_project_id" - add_index "time_entries", ["user_id"], :name => "index_time_entries_on_user_id" - - create_table "tokens", :force => true do |t| - t.integer "user_id", :default => 0, :null => false - t.string "action", :limit => 30, :default => "", :null => false - t.string "value", :limit => 40, :default => "", :null => false - t.datetime "created_on", :null => false - end - - add_index "tokens", ["user_id"], :name => "index_tokens_on_user_id" - add_index "tokens", ["value"], :name => "tokens_value", :unique => true - - create_table "trackers", :force => true do |t| - t.string "name", :limit => 30, :default => "", :null => false - t.boolean "is_in_chlog", :default => false, :null => false - t.integer "position", :default => 1 - t.boolean "is_in_roadmap", :default => true, :null => false - t.integer "fields_bits", :default => 0 - end - - create_table "user_actions", :force => true do |t| - t.integer "user_id" - t.string "action_type" - t.integer "action_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "user_activities", :force => true do |t| - t.string "act_type" - t.integer "act_id" - t.string "container_type" - t.integer "container_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "user_id" - end - - add_index "user_activities", ["act_id", "act_type", "container_id", "created_at"], :name => "user_act_index" - - create_table "user_extensions", :force => true do |t| - t.integer "user_id", :null => false - t.date "birthday" - t.string "brief_introduction" - t.integer "gender" - t.string "location" - t.string "occupation" - t.integer "work_experience" - t.integer "zip_code" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.string "technical_title" - t.integer "identity" - t.string "student_id" - t.string "teacher_realname" - t.string "student_realname" - t.string "location_city" - t.integer "school_id" - t.string "description", :default => "" - end - - create_table "user_feedback_messages", :force => true do |t| - t.integer "user_id" - t.integer "journals_for_message_id" - t.string "journals_for_message_type" - t.integer "viewed" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - add_index "user_feedback_messages", ["journals_for_message_id"], :name => "index_user_feedback_messages_on_journals_for_message_id" - add_index "user_feedback_messages", ["user_id", "created_at"], :name => "index_user_feedback_messages_on_user_id_and_created_at" - - create_table "user_grades", :force => true do |t| - t.integer "user_id", :null => false - t.integer "project_id", :null => false - t.float "grade", :default => 0.0 - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - add_index "user_grades", ["grade"], :name => "index_user_grades_on_grade" - add_index "user_grades", ["project_id"], :name => "index_user_grades_on_project_id" - add_index "user_grades", ["user_id"], :name => "index_user_grades_on_user_id" - - create_table "user_levels", :force => true do |t| - t.integer "user_id" - t.integer "level" - end - - create_table "user_preferences", :force => true do |t| - t.integer "user_id", :default => 0, :null => false - t.text "others" - t.boolean "hide_mail", :default => false - t.string "time_zone" - end - - add_index "user_preferences", ["user_id"], :name => "index_user_preferences_on_user_id" - - create_table "user_score_details", :force => true do |t| - t.integer "current_user_id" - t.integer "target_user_id" - t.string "score_type" - t.string "score_action" - t.integer "user_id" - t.integer "old_score" - t.integer "new_score" - t.integer "current_user_level" - t.integer "target_user_level" - t.integer "score_changeable_obj_id" - t.string "score_changeable_obj_type" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "user_scores", :force => true do |t| - t.integer "user_id", :null => false - t.integer "collaboration" - t.integer "influence" - t.integer "skill" - t.integer "active" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "user_statuses", :force => true do |t| - t.integer "changesets_count" - t.integer "watchers_count" - t.integer "user_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.float "grade", :default => 0.0 - end - - add_index "user_statuses", ["changesets_count"], :name => "index_user_statuses_on_changesets_count" - add_index "user_statuses", ["grade"], :name => "index_user_statuses_on_grade" - add_index "user_statuses", ["watchers_count"], :name => "index_user_statuses_on_watchers_count" - - create_table "user_wechats", :force => true do |t| - t.integer "subscribe" - t.string "openid" - t.string "nickname" - t.integer "sex" - t.string "language" - t.string "city" - t.string "province" - t.string "country" - t.string "headimgurl" - t.string "subscribe_time" - t.string "unionid" - t.string "remark" - t.integer "groupid" - t.integer "user_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "users", :force => true do |t| - t.string "login", :default => "", :null => false - t.string "hashed_password", :limit => 40, :default => "", :null => false - t.string "firstname", :limit => 30, :default => "", :null => false - t.string "lastname", :default => "", :null => false - t.string "mail", :limit => 60, :default => "", :null => false - t.boolean "admin", :default => false, :null => false - t.integer "status", :default => 1, :null => false - t.datetime "last_login_on" - t.string "language", :limit => 5, :default => "" - t.integer "auth_source_id" - t.datetime "created_on" - t.datetime "updated_on" - t.string "type" - t.string "identity_url" - t.string "mail_notification", :default => "", :null => false - t.string "salt", :limit => 64 - t.integer "gid" - t.integer "visits", :default => 0 - t.integer "excellent_teacher", :default => 0 - t.integer "excellent_student", :default => 0 - end - - add_index "users", ["auth_source_id"], :name => "index_users_on_auth_source_id" - add_index "users", ["id", "type"], :name => "index_users_on_id_and_type" - add_index "users", ["type"], :name => "index_users_on_type" - - create_table "versions", :force => true do |t| - t.integer "project_id", :default => 0, :null => false - t.string "name", :default => "", :null => false - t.string "description", :default => "" - t.date "effective_date" - t.datetime "created_on" - t.datetime "updated_on" - t.string "wiki_page_title" - t.string "status", :default => "open" - t.string "sharing", :default => "none", :null => false - end - - add_index "versions", ["project_id"], :name => "versions_project_id" - add_index "versions", ["sharing"], :name => "index_versions_on_sharing" - - create_table "visitors", :force => true do |t| - t.integer "user_id" - t.integer "master_id" - t.datetime "updated_on" - t.datetime "created_on" - end - - add_index "visitors", ["master_id"], :name => "index_visitors_master_id" - add_index "visitors", ["updated_on"], :name => "index_visitors_updated_on" - add_index "visitors", ["user_id"], :name => "index_visitors_user_id" - - create_table "watchers", :force => true do |t| - t.string "watchable_type", :default => "", :null => false - t.integer "watchable_id", :default => 0, :null => false - t.integer "user_id" - end - - add_index "watchers", ["user_id", "watchable_type"], :name => "watchers_user_id_type" - add_index "watchers", ["user_id"], :name => "index_watchers_on_user_id" - add_index "watchers", ["watchable_id", "watchable_type"], :name => "index_watchers_on_watchable_id_and_watchable_type" - - create_table "web_footer_companies", :force => true do |t| - t.string "name" - t.string "logo_size" - t.string "url" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "web_footer_oranizers", :force => true do |t| - t.string "name" - t.text "description" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "wechat_logs", :force => true do |t| - t.string "openid", :null => false - t.text "request_raw" - t.text "response_raw" - t.text "session_raw" - t.datetime "created_at", :null => false - end - - add_index "wechat_logs", ["openid"], :name => "index_wechat_logs_on_openid" - - create_table "wiki_content_versions", :force => true do |t| - t.integer "wiki_content_id", :null => false - t.integer "page_id", :null => false - t.integer "author_id" - t.binary "data", :limit => 2147483647 - t.string "compression", :limit => 6, :default => "" - t.string "comments", :default => "" - t.datetime "updated_on", :null => false - t.integer "version", :null => false - end - - add_index "wiki_content_versions", ["updated_on"], :name => "index_wiki_content_versions_on_updated_on" - add_index "wiki_content_versions", ["wiki_content_id"], :name => "wiki_content_versions_wcid" - - create_table "wiki_contents", :force => true do |t| - t.integer "page_id", :null => false - t.integer "author_id" - t.text "text", :limit => 2147483647 - t.string "comments", :default => "" - t.datetime "updated_on", :null => false - t.integer "version", :null => false - end - - add_index "wiki_contents", ["author_id"], :name => "index_wiki_contents_on_author_id" - add_index "wiki_contents", ["page_id"], :name => "wiki_contents_page_id" - - create_table "wiki_pages", :force => true do |t| - t.integer "wiki_id", :null => false - t.string "title", :null => false - t.datetime "created_on", :null => false - t.boolean "protected", :default => false, :null => false - t.integer "parent_id" - end - - add_index "wiki_pages", ["parent_id"], :name => "index_wiki_pages_on_parent_id" - add_index "wiki_pages", ["wiki_id", "title"], :name => "wiki_pages_wiki_id_title" - add_index "wiki_pages", ["wiki_id"], :name => "index_wiki_pages_on_wiki_id" - - create_table "wiki_redirects", :force => true do |t| - t.integer "wiki_id", :null => false - t.string "title" - t.string "redirects_to" - t.datetime "created_on", :null => false - end - - add_index "wiki_redirects", ["wiki_id", "title"], :name => "wiki_redirects_wiki_id_title" - add_index "wiki_redirects", ["wiki_id"], :name => "index_wiki_redirects_on_wiki_id" - - create_table "wikis", :force => true do |t| - t.integer "project_id", :null => false - t.string "start_page", :null => false - t.integer "status", :default => 1, :null => false - end - - add_index "wikis", ["project_id"], :name => "wikis_project_id" - - create_table "workflows", :force => true do |t| - t.integer "tracker_id", :default => 0, :null => false - t.integer "old_status_id", :default => 0, :null => false - t.integer "new_status_id", :default => 0, :null => false - t.integer "role_id", :default => 0, :null => false - t.boolean "assignee", :default => false, :null => false - t.boolean "author", :default => false, :null => false - t.string "type", :limit => 30 - t.string "field_name", :limit => 30 - t.string "rule", :limit => 30 - end - - add_index "workflows", ["new_status_id"], :name => "index_workflows_on_new_status_id" - add_index "workflows", ["old_status_id"], :name => "index_workflows_on_old_status_id" - add_index "workflows", ["role_id", "tracker_id", "old_status_id"], :name => "wkfs_role_tracker_old_status" - add_index "workflows", ["role_id"], :name => "index_workflows_on_role_id" - - create_table "works_categories", :force => true do |t| - t.string "category" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "zip_packs", :force => true do |t| - t.integer "user_id" - t.integer "homework_id" - t.string "file_digest" - t.string "file_path" - t.integer "pack_times", :default => 1 - t.integer "pack_size", :default => 0 - t.text "file_digests" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - -end +# encoding: UTF-8 +# This file is auto-generated from the current state of the database. Instead +# of editing this file, please use the migrations feature of Active Record to +# incrementally modify your database, and then regenerate this schema definition. +# +# Note that this schema.rb definition is the authoritative source for your +# database schema. If you need to create the application database on another +# system, you should be using db:schema:load, not running all the migrations +# from scratch. The latter is a flawed and unsustainable approach (the more migrations +# you'll amass, the slower it'll run and the greater likelihood for issues). +# +# It's strongly recommended to check this file into your version control system. + +ActiveRecord::Schema.define(:version => 20160729124833) do + + create_table "activities", :force => true do |t| + t.integer "act_id", :null => false + t.string "act_type", :null => false + t.integer "user_id", :null => false + t.integer "activity_container_id" + t.string "activity_container_type", :default => "" + t.datetime "created_at" + end + + add_index "activities", ["act_id", "act_type"], :name => "index_activities_on_act_id_and_act_type" + add_index "activities", ["user_id", "act_type"], :name => "index_activities_on_user_id_and_act_type" + add_index "activities", ["user_id"], :name => "index_activities_on_user_id" + + create_table "activity_notifies", :force => true do |t| + t.integer "activity_container_id" + t.string "activity_container_type" + t.integer "activity_id" + t.string "activity_type" + t.integer "notify_to" + t.datetime "created_on" + t.integer "is_read" + end + + add_index "activity_notifies", ["activity_container_id", "activity_container_type"], :name => "index_an_activity_container_id" + add_index "activity_notifies", ["created_on"], :name => "index_an_created_on" + add_index "activity_notifies", ["notify_to"], :name => "index_an_notify_to" + + create_table "api_keys", :force => true do |t| + t.string "access_token" + t.datetime "expires_at" + t.integer "user_id" + t.boolean "active", :default => true + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "api_keys", ["access_token"], :name => "index_api_keys_on_access_token" + add_index "api_keys", ["user_id"], :name => "index_api_keys_on_user_id" + + create_table "applied_messages", :force => true do |t| + t.integer "user_id" + t.integer "applied_id" + t.string "applied_type" + t.integer "viewed", :default => 0 + t.integer "status", :default => 0 + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "name" + t.integer "applied_user_id" + t.integer "role" + t.integer "project_id" + end + + create_table "applied_projects", :force => true do |t| + t.integer "project_id", :null => false + t.integer "user_id", :null => false + t.integer "role", :default => 0 + end + + create_table "apply_add_schools", :force => true do |t| + t.string "name" + t.string "province" + t.string "city" + t.string "address" + t.string "remarks" + t.integer "school_id" + t.integer "status", :default => 0 + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "user_id" + end + + create_table "apply_homeworks", :force => true do |t| + t.integer "status" + t.integer "user_id" + t.integer "homework_common_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "apply_homeworks", ["homework_common_id"], :name => "index_apply_homeworks_on_homework_common_id" + add_index "apply_homeworks", ["user_id"], :name => "index_apply_homeworks_on_user_id" + + create_table "apply_project_masters", :force => true do |t| + t.integer "user_id" + t.string "apply_type" + t.integer "apply_id" + t.integer "status" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "apply_resources", :force => true do |t| + t.integer "status" + t.integer "user_id" + t.integer "attachment_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "container_id" + t.string "container_type" + t.text "content" + t.integer "apply_user_id" + end + + create_table "at_messages", :force => true do |t| + t.integer "user_id" + t.integer "at_message_id" + t.string "at_message_type" + t.boolean "viewed", :default => false + t.string "container_type" + t.integer "container_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "sender_id" + end + + add_index "at_messages", ["user_id"], :name => "index_at_messages_on_user_id" + + create_table "attachment_histories", :force => true do |t| + t.integer "container_id" + t.string "container_type" + t.string "filename", :default => "" + t.string "disk_filename", :default => "" + t.integer "filesize", :default => 0 + t.string "content_type", :default => "" + t.string "digest", :limit => 40, :default => "" + t.integer "downloads", :default => 0 + t.integer "author_id" + t.datetime "created_on" + t.string "description" + t.string "disk_directory" + t.integer "attachtype" + t.integer "is_public" + t.integer "copy_from" + t.integer "quotes" + t.integer "version" + t.integer "attachment_id" + t.integer "is_publish", :default => 1 + t.date "publish_time" + end + + create_table "attachments", :force => true do |t| + t.integer "container_id" + t.string "container_type", :limit => 30 + t.string "filename", :default => "", :null => false + t.string "disk_filename", :default => "", :null => false + t.integer "filesize", :default => 0, :null => false + t.string "content_type", :default => "" + t.string "digest", :limit => 40, :default => "", :null => false + t.integer "downloads", :default => 0, :null => false + t.integer "author_id", :default => 0, :null => false + t.datetime "created_on" + t.string "description" + t.string "disk_directory" + t.integer "attachtype", :default => 1 + t.integer "is_public", :default => 1 + t.integer "copy_from" + t.integer "quotes" + t.integer "is_publish", :default => 1 + t.date "publish_time" + end + + add_index "attachments", ["author_id"], :name => "index_attachments_on_author_id" + add_index "attachments", ["container_id", "container_type"], :name => "index_attachments_on_container_id_and_container_type" + add_index "attachments", ["created_on"], :name => "index_attachments_on_created_on" + + create_table "attachmentstypes", :force => true do |t| + t.integer "typeId", :null => false + t.string "typeName", :limit => 50 + end + + create_table "auth_sources", :force => true do |t| + t.string "type", :limit => 30, :default => "", :null => false + t.string "name", :limit => 60, :default => "", :null => false + t.string "host", :limit => 60 + t.integer "port" + t.string "account" + t.string "account_password", :default => "" + t.string "base_dn" + t.string "attr_login", :limit => 30 + t.string "attr_firstname", :limit => 30 + t.string "attr_lastname", :limit => 30 + t.string "attr_mail", :limit => 30 + t.boolean "onthefly_register", :default => false, :null => false + t.boolean "tls", :default => false, :null => false + t.string "filter" + t.integer "timeout" + end + + add_index "auth_sources", ["id", "type"], :name => "index_auth_sources_on_id_and_type" + + create_table "biding_projects", :force => true do |t| + t.integer "project_id" + t.integer "bid_id" + t.integer "user_id" + t.string "description" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "reward" + end + + create_table "bids", :force => true do |t| + t.string "name" + t.string "budget", :null => false + t.integer "author_id" + t.date "deadline" + t.text "description" + t.datetime "created_on", :null => false + t.datetime "updated_on", :null => false + t.integer "commit" + t.integer "reward_type" + t.integer "homework_type" + t.integer "parent_id" + t.string "password" + t.integer "is_evaluation" + t.integer "proportion", :default => 60 + t.integer "comment_status", :default => 0 + t.integer "evaluation_num", :default => 3 + t.integer "open_anonymous_evaluation", :default => 1 + end + + create_table "blog_comments", :force => true do |t| + t.integer "blog_id", :null => false + t.integer "parent_id" + t.string "title", :default => "", :null => false + t.text "content" + t.integer "author_id" + t.integer "comments_count", :default => 0, :null => false + t.integer "last_comment_id" + t.datetime "created_on", :null => false + t.datetime "updated_on", :null => false + t.boolean "locked", :default => false + t.integer "sticky", :default => 0 + t.integer "reply_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "blogs", :force => true do |t| + t.string "name", :default => "", :null => false + t.text "description" + t.integer "position", :default => 1 + t.integer "article_count", :default => 0, :null => false + t.integer "comments_count", :default => 0, :null => false + t.integer "last_comments_id" + t.integer "parent_id" + t.integer "author_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "homepage_id" + end + + create_table "boards", :force => true do |t| + t.integer "project_id", :null => false + t.string "name", :default => "", :null => false + t.string "description" + t.integer "position", :default => 1 + t.integer "topics_count", :default => 0, :null => false + t.integer "messages_count", :default => 0, :null => false + t.integer "last_message_id" + t.integer "parent_id" + t.integer "course_id" + t.integer "org_subfield_id" + end + + add_index "boards", ["last_message_id"], :name => "index_boards_on_last_message_id" + add_index "boards", ["project_id"], :name => "boards_project_id" + + create_table "bug_to_osps", :force => true do |t| + t.integer "osp_id" + t.integer "relative_memo_id" + t.string "description" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "changes", :force => true do |t| + t.integer "changeset_id", :null => false + t.string "action", :limit => 1, :default => "", :null => false + t.text "path", :null => false + t.text "from_path" + t.string "from_revision" + t.string "revision" + t.string "branch" + end + + add_index "changes", ["changeset_id"], :name => "changesets_changeset_id" + + create_table "changeset_parents", :id => false, :force => true do |t| + t.integer "changeset_id", :null => false + t.integer "parent_id", :null => false + end + + add_index "changeset_parents", ["changeset_id"], :name => "changeset_parents_changeset_ids" + add_index "changeset_parents", ["parent_id"], :name => "changeset_parents_parent_ids" + + create_table "changesets", :force => true do |t| + t.integer "repository_id", :null => false + t.string "revision", :null => false + t.string "committer" + t.datetime "committed_on", :null => false + t.text "comments" + t.date "commit_date" + t.string "scmid" + t.integer "user_id" + end + + add_index "changesets", ["committed_on"], :name => "index_changesets_on_committed_on" + add_index "changesets", ["repository_id", "revision"], :name => "changesets_repos_rev", :unique => true + add_index "changesets", ["repository_id", "scmid"], :name => "changesets_repos_scmid" + add_index "changesets", ["repository_id"], :name => "index_changesets_on_repository_id" + add_index "changesets", ["user_id"], :name => "index_changesets_on_user_id" + + create_table "changesets_issues", :id => false, :force => true do |t| + t.integer "changeset_id", :null => false + t.integer "issue_id", :null => false + end + + add_index "changesets_issues", ["changeset_id", "issue_id"], :name => "changesets_issues_ids", :unique => true + + create_table "code_review_assignments", :force => true do |t| + t.integer "issue_id" + t.integer "change_id" + t.integer "attachment_id" + t.string "file_path" + t.string "rev" + t.string "rev_to" + t.string "action_type" + t.integer "changeset_id" + end + + create_table "code_review_project_settings", :force => true do |t| + t.integer "project_id" + t.integer "tracker_id" + t.datetime "created_at" + t.datetime "updated_at" + t.integer "updated_by" + t.boolean "hide_code_review_tab", :default => false + t.integer "auto_relation", :default => 1 + t.integer "assignment_tracker_id" + t.text "auto_assign" + t.integer "lock_version", :default => 0, :null => false + t.boolean "tracker_in_review_dialog", :default => false + end + + create_table "code_review_user_settings", :force => true do |t| + t.integer "user_id", :default => 0, :null => false + t.integer "mail_notification", :default => 0, :null => false + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "code_reviews", :force => true do |t| + t.integer "project_id" + t.integer "change_id" + t.datetime "created_at" + t.datetime "updated_at" + t.integer "line" + t.integer "updated_by_id" + t.integer "lock_version", :default => 0, :null => false + t.integer "status_changed_from" + t.integer "status_changed_to" + t.integer "issue_id" + t.string "action_type" + t.string "file_path" + t.string "rev" + t.string "rev_to" + t.integer "attachment_id" + t.integer "file_count", :default => 0, :null => false + t.boolean "diff_all" + end + + create_table "code_tests", :force => true do |t| + t.integer "homework_id" + t.integer "wait_time", :default => 0 + t.integer "language" + t.integer "status" + t.integer "time_used", :default => 0 + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "student_work_id", :default => 0 + end + + create_table "comments", :force => true do |t| + t.string "commented_type", :limit => 30, :default => "", :null => false + t.integer "commented_id", :default => 0, :null => false + t.integer "author_id", :default => 0, :null => false + t.text "comments" + t.datetime "created_on", :null => false + t.datetime "updated_on", :null => false + t.integer "parent_id" + t.integer "comments_count", :default => 0 + t.integer "reply_id" + end + + add_index "comments", ["author_id"], :name => "index_comments_on_author_id" + add_index "comments", ["commented_id", "commented_type"], :name => "index_comments_on_commented_id_and_commented_type" + + create_table "commits", :force => true do |t| + t.integer "repository_id" + t.string "version" + t.string "committer" + t.text "comments" + t.datetime "committed_on" + t.integer "project_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "contest_notifications", :force => true do |t| + t.text "title" + t.text "content" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "contesting_projects", :force => true do |t| + t.integer "project_id" + t.string "contest_id" + t.integer "user_id" + t.string "description" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "reward" + end + + create_table "contesting_softapplications", :force => true do |t| + t.integer "softapplication_id" + t.integer "contest_id" + t.integer "user_id" + t.string "description" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "reward" + end + + create_table "contestnotifications", :force => true do |t| + t.integer "contest_id" + t.string "title" + t.string "summary" + t.text "description" + t.integer "author_id" + t.integer "notificationcomments_count" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "contests", :force => true do |t| + t.string "name" + t.string "budget", :default => "" + t.integer "author_id" + t.date "deadline" + t.string "description" + t.integer "commit" + t.string "password" + t.datetime "created_on", :null => false + t.datetime "updated_on", :null => false + end + + create_table "course_activities", :force => true do |t| + t.integer "user_id" + t.integer "course_id" + t.integer "course_act_id" + t.string "course_act_type" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "course_activities", ["course_id", "course_act_id", "course_act_type", "created_at"], :name => "course_act_index" + + create_table "course_attachments", :force => true do |t| + t.string "filename" + t.string "disk_filename" + t.integer "filesize" + t.string "content_type" + t.string "digest" + t.integer "downloads" + t.string "author_id" + t.string "integer" + t.string "description" + t.string "disk_directory" + t.integer "attachtype" + t.integer "is_public" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "container_id", :default => 0 + end + + create_table "course_contributor_scores", :force => true do |t| + t.integer "course_id" + t.integer "user_id" + t.integer "message_num", :default => 0 + t.integer "message_reply_num", :default => 0 + t.integer "news_reply_num", :default => 0 + t.integer "resource_num", :default => 0 + t.integer "journal_num", :default => 0 + t.integer "journal_reply_num", :default => 0 + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "total_score", :default => 0 + t.integer "homework_journal_num", :default => 0 + t.integer "news_num", :default => 0 + end + + create_table "course_groups", :force => true do |t| + t.string "name" + t.integer "course_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "course_infos", :force => true do |t| + t.integer "course_id" + t.integer "user_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "course_messages", :force => true do |t| + t.integer "user_id" + t.integer "course_id" + t.integer "course_message_id" + t.string "course_message_type" + t.integer "viewed" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.text "content" + t.integer "status" + t.integer "apply_user_id" + t.integer "apply_result" + end + + add_index "course_messages", ["course_message_type"], :name => "index_course_messages_on_course_message_type" + add_index "course_messages", ["user_id", "course_id", "created_at"], :name => "index_course_messages_on_user_id_and_course_id_and_created_at" + + create_table "course_statuses", :force => true do |t| + t.integer "changesets_count" + t.integer "watchers_count" + t.integer "course_id" + t.float "grade", :default => 0.0 + t.integer "course_ac_para", :default => 0 + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "courses", :force => true do |t| + t.integer "tea_id" + t.string "name" + t.integer "state" + t.string "code" + t.integer "time" + t.string "extra" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "location" + t.string "term" + t.string "string" + t.string "password" + t.string "setup_time" + t.string "endup_time" + t.string "class_period" + t.integer "school_id" + t.text "description" + t.integer "status", :default => 1 + t.integer "attachmenttype", :default => 2 + t.integer "lft" + t.integer "rgt" + t.integer "is_public", :limit => 1, :default => 1 + t.integer "inherit_members", :limit => 1, :default => 1 + t.integer "open_student", :default => 0 + t.integer "outline", :default => 0 + t.integer "publish_resource", :default => 0 + t.integer "is_delete", :default => 0 + t.integer "end_time" + t.string "end_term" + t.integer "is_excellent", :default => 0 + t.integer "excellent_option", :default => 0 + t.integer "is_copy", :default => 0 + t.integer "visits", :default => 0 + t.integer "syllabus_id" + t.string "invite_code" + t.string "qrcode" + end + + add_index "courses", ["invite_code"], :name => "index_courses_on_invite_code", :unique => true + add_index "courses", ["syllabus_id"], :name => "index_courses_on_syllabus_id" + + create_table "custom_fields", :force => true do |t| + t.string "type", :limit => 30, :default => "", :null => false + t.string "name", :limit => 30, :default => "", :null => false + t.string "field_format", :limit => 30, :default => "", :null => false + t.text "possible_values" + t.string "regexp", :default => "" + t.integer "min_length", :default => 0, :null => false + t.integer "max_length", :default => 0, :null => false + t.boolean "is_required", :default => false, :null => false + t.boolean "is_for_all", :default => false, :null => false + t.boolean "is_filter", :default => false, :null => false + t.integer "position", :default => 1 + t.boolean "searchable", :default => false + t.text "default_value" + t.boolean "editable", :default => true + t.boolean "visible", :default => true, :null => false + t.boolean "multiple", :default => false + end + + add_index "custom_fields", ["id", "type"], :name => "index_custom_fields_on_id_and_type" + + create_table "custom_fields_projects", :id => false, :force => true do |t| + t.integer "custom_field_id", :default => 0, :null => false + t.integer "project_id", :default => 0, :null => false + end + + add_index "custom_fields_projects", ["custom_field_id", "project_id"], :name => "index_custom_fields_projects_on_custom_field_id_and_project_id", :unique => true + + create_table "custom_fields_trackers", :id => false, :force => true do |t| + t.integer "custom_field_id", :default => 0, :null => false + t.integer "tracker_id", :default => 0, :null => false + end + + add_index "custom_fields_trackers", ["custom_field_id", "tracker_id"], :name => "index_custom_fields_trackers_on_custom_field_id_and_tracker_id", :unique => true + + create_table "custom_values", :force => true do |t| + t.string "customized_type", :limit => 30, :default => "", :null => false + t.integer "customized_id", :default => 0, :null => false + t.integer "custom_field_id", :default => 0, :null => false + t.text "value" + end + + add_index "custom_values", ["custom_field_id"], :name => "index_custom_values_on_custom_field_id" + add_index "custom_values", ["customized_type", "customized_id"], :name => "custom_values_customized" + + create_table "delayed_jobs", :force => true do |t| + t.integer "priority", :default => 0, :null => false + t.integer "attempts", :default => 0, :null => false + t.text "handler", :null => false + t.text "last_error" + t.datetime "run_at" + t.datetime "locked_at" + t.datetime "failed_at" + t.string "locked_by" + t.string "queue" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "delayed_jobs", ["priority", "run_at"], :name => "delayed_jobs_priority" + + create_table "discuss_demos", :force => true do |t| + t.string "title" + t.text "body" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "documents", :force => true do |t| + t.integer "project_id", :default => 0, :null => false + t.integer "category_id", :default => 0, :null => false + t.string "title", :limit => 60, :default => "", :null => false + t.text "description" + t.datetime "created_on" + t.integer "user_id", :default => 0 + t.integer "is_public", :default => 1 + end + + add_index "documents", ["category_id"], :name => "index_documents_on_category_id" + add_index "documents", ["created_on"], :name => "index_documents_on_created_on" + add_index "documents", ["project_id"], :name => "documents_project_id" + + create_table "dts", :primary_key => "Num", :force => true do |t| + t.string "Defect", :limit => 50 + t.string "Category", :limit => 50 + t.string "File" + t.string "Method" + t.string "Module", :limit => 20 + t.string "Variable", :limit => 50 + t.integer "StartLine" + t.integer "IPLine" + t.string "IPLineCode", :limit => 200 + t.string "Judge", :limit => 15 + t.integer "Review", :limit => 1 + t.string "Description" + t.text "PreConditions", :limit => 2147483647 + t.text "TraceInfo", :limit => 2147483647 + t.text "Code", :limit => 2147483647 + t.integer "project_id" + t.datetime "created_at" + t.datetime "updated_at" + t.integer "id", :null => false + end + + create_table "editor_of_documents", :force => true do |t| + t.integer "editor_id" + t.integer "org_document_comment_id" + t.datetime "created_at" + end + + create_table "enabled_modules", :force => true do |t| + t.integer "project_id" + t.string "name", :null => false + t.integer "course_id" + end + + add_index "enabled_modules", ["project_id"], :name => "enabled_modules_project_id" + + create_table "enumerations", :force => true do |t| + t.string "name", :limit => 30, :default => "", :null => false + t.integer "position", :default => 1 + t.boolean "is_default", :default => false, :null => false + t.string "type" + t.boolean "active", :default => true, :null => false + t.integer "project_id" + t.integer "parent_id" + t.string "position_name", :limit => 30 + end + + add_index "enumerations", ["id", "type"], :name => "index_enumerations_on_id_and_type" + add_index "enumerations", ["project_id"], :name => "index_enumerations_on_project_id" + + create_table "exercise_answers", :force => true do |t| + t.integer "user_id" + t.integer "exercise_question_id" + t.integer "exercise_choice_id" + t.text "answer_text" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "exercise_choices", :force => true do |t| + t.integer "exercise_question_id" + t.text "choice_text" + t.integer "choice_position" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "exercise_questions", :force => true do |t| + t.text "question_title" + t.integer "question_type" + t.integer "question_number" + t.integer "exercise_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "question_score" + end + + create_table "exercise_standard_answers", :force => true do |t| + t.integer "exercise_question_id" + t.integer "exercise_choice_id" + t.text "answer_text" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "exercise_users", :force => true do |t| + t.integer "user_id" + t.integer "exercise_id" + t.integer "score" + t.datetime "start_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.datetime "end_at" + t.integer "status" + end + + create_table "exercises", :force => true do |t| + t.text "exercise_name" + t.text "exercise_description" + t.integer "course_id" + t.integer "exercise_status" + t.integer "user_id" + t.integer "time" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.datetime "publish_time" + t.datetime "end_time" + t.integer "show_result" + end + + create_table "first_pages", :force => true do |t| + t.string "web_title" + t.string "title" + t.text "description" + t.string "page_type" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "sort_type" + t.integer "image_width", :default => 107 + t.integer "image_height", :default => 63 + t.integer "show_course", :default => 1 + t.integer "show_contest", :default => 1 + end + + create_table "forge_activities", :force => true do |t| + t.integer "user_id" + t.integer "project_id" + t.integer "forge_act_id" + t.string "forge_act_type" + t.integer "org_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "forge_activities", ["forge_act_id"], :name => "index_forge_activities_on_forge_act_id" + add_index "forge_activities", ["project_id", "forge_act_id", "created_at", "forge_act_type"], :name => "forge_act_index" + + create_table "forge_messages", :force => true do |t| + t.integer "user_id" + t.integer "project_id" + t.integer "forge_message_id" + t.string "forge_message_type" + t.integer "viewed" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "secret_key" + t.integer "status" + end + + add_index "forge_messages", ["forge_message_id", "forge_message_type"], :name => "index_forge_messages_on_forge_message_id_and_forge_message_type" + add_index "forge_messages", ["user_id", "project_id", "created_at"], :name => "index_forge_messages_on_user_id_and_project_id_and_created_at" + + create_table "forums", :force => true do |t| + t.string "name", :null => false + t.text "description" + t.integer "topic_count", :default => 0 + t.integer "memo_count", :default => 0 + t.integer "last_memo_id", :default => 0 + t.integer "creator_id", :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "sticky" + t.integer "locked" + end + + create_table "forwards", :force => true do |t| + t.integer "from_id" + t.string "from_type" + t.integer "to_id" + t.string "to_type" + t.datetime "created_at" + end + + create_table "groups_users", :id => false, :force => true do |t| + t.integer "group_id", :null => false + t.integer "user_id", :null => false + end + + add_index "groups_users", ["group_id", "user_id"], :name => "groups_users_ids", :unique => true + + create_table "homework_attaches", :force => true do |t| + t.integer "bid_id" + t.integer "user_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "reward" + t.string "name" + t.text "description" + t.integer "state" + t.integer "project_id", :default => 0 + t.float "score", :default => 0.0 + t.integer "is_teacher_score", :default => 0 + end + + add_index "homework_attaches", ["bid_id"], :name => "index_homework_attaches_on_bid_id" + + create_table "homework_commons", :force => true do |t| + t.string "name" + t.integer "user_id" + t.text "description" + t.date "publish_time" + t.date "end_time" + t.integer "homework_type", :default => 1 + t.string "late_penalty" + t.integer "course_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "teacher_priority", :default => 1 + t.integer "anonymous_comment", :default => 0 + t.integer "quotes", :default => 0 + t.integer "is_open", :default => 0 + t.datetime "simi_time" + end + + add_index "homework_commons", ["course_id", "id"], :name => "index_homework_commons_on_course_id_and_id" + + create_table "homework_detail_groups", :force => true do |t| + t.integer "homework_common_id" + t.integer "min_num" + t.integer "max_num" + t.integer "base_on_project" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "homework_detail_groups", ["homework_common_id"], :name => "index_homework_detail_groups_on_homework_common_id" + + create_table "homework_detail_manuals", :force => true do |t| + t.float "ta_proportion" + t.integer "comment_status" + t.date "evaluation_start" + t.date "evaluation_end" + t.integer "evaluation_num" + t.integer "absence_penalty", :default => 1 + t.integer "homework_common_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "homework_detail_programings", :force => true do |t| + t.string "language" + t.text "standard_code", :limit => 2147483647 + t.integer "homework_common_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.float "ta_proportion", :default => 0.1 + t.integer "question_id" + end + + create_table "homework_evaluations", :force => true do |t| + t.string "user_id" + t.string "homework_attach_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "homework_for_courses", :force => true do |t| + t.integer "course_id" + t.integer "bid_id" + end + + add_index "homework_for_courses", ["bid_id"], :name => "index_homework_for_courses_on_bid_id" + add_index "homework_for_courses", ["course_id"], :name => "index_homework_for_courses_on_course_id" + + create_table "homework_tests", :force => true do |t| + t.text "input" + t.text "output" + t.integer "homework_common_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "result" + t.text "error_msg" + end + + create_table "homework_users", :force => true do |t| + t.string "homework_attach_id" + t.string "user_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "invite_lists", :force => true do |t| + t.integer "project_id" + t.integer "user_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "mail" + end + + create_table "issue_categories", :force => true do |t| + t.integer "project_id", :default => 0, :null => false + t.string "name", :limit => 30, :default => "", :null => false + t.integer "assigned_to_id" + end + + add_index "issue_categories", ["assigned_to_id"], :name => "index_issue_categories_on_assigned_to_id" + add_index "issue_categories", ["project_id"], :name => "issue_categories_project_id" + + create_table "issue_relations", :force => true do |t| + t.integer "issue_from_id", :null => false + t.integer "issue_to_id", :null => false + t.string "relation_type", :default => "", :null => false + t.integer "delay" + end + + add_index "issue_relations", ["issue_from_id", "issue_to_id"], :name => "index_issue_relations_on_issue_from_id_and_issue_to_id", :unique => true + add_index "issue_relations", ["issue_from_id"], :name => "index_issue_relations_on_issue_from_id" + add_index "issue_relations", ["issue_to_id"], :name => "index_issue_relations_on_issue_to_id" + + create_table "issue_statuses", :force => true do |t| + t.string "name", :limit => 30, :default => "", :null => false + t.boolean "is_closed", :default => false, :null => false + t.boolean "is_default", :default => false, :null => false + t.integer "position", :default => 1 + t.integer "default_done_ratio" + end + + add_index "issue_statuses", ["is_closed"], :name => "index_issue_statuses_on_is_closed" + add_index "issue_statuses", ["is_default"], :name => "index_issue_statuses_on_is_default" + add_index "issue_statuses", ["position"], :name => "index_issue_statuses_on_position" + + create_table "issues", :force => true do |t| + t.integer "tracker_id", :null => false + t.integer "project_id", :null => false + t.string "subject", :default => "", :null => false + t.text "description" + t.date "due_date" + t.integer "category_id" + t.integer "status_id", :null => false + t.integer "assigned_to_id" + t.integer "priority_id", :null => false + t.integer "fixed_version_id" + t.integer "author_id", :null => false + t.integer "lock_version", :default => 0, :null => false + t.datetime "created_on" + t.datetime "updated_on" + t.date "start_date" + t.integer "done_ratio", :default => 0, :null => false + t.float "estimated_hours" + t.integer "parent_id" + t.integer "root_id" + t.integer "lft" + t.integer "rgt" + t.boolean "is_private", :default => false, :null => false + t.datetime "closed_on" + t.integer "project_issues_index" + end + + add_index "issues", ["assigned_to_id"], :name => "index_issues_on_assigned_to_id" + add_index "issues", ["author_id"], :name => "index_issues_on_author_id" + add_index "issues", ["category_id"], :name => "index_issues_on_category_id" + add_index "issues", ["created_on"], :name => "index_issues_on_created_on" + add_index "issues", ["fixed_version_id"], :name => "index_issues_on_fixed_version_id" + add_index "issues", ["priority_id"], :name => "index_issues_on_priority_id" + add_index "issues", ["project_id"], :name => "issues_project_id" + add_index "issues", ["root_id", "lft", "rgt"], :name => "index_issues_on_root_id_and_lft_and_rgt" + add_index "issues", ["status_id"], :name => "index_issues_on_status_id" + add_index "issues", ["tracker_id"], :name => "index_issues_on_tracker_id" + + create_table "join_in_competitions", :force => true do |t| + t.integer "user_id" + t.integer "competition_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "join_in_contests", :force => true do |t| + t.integer "user_id" + t.integer "bid_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "journal_details", :force => true do |t| + t.integer "journal_id", :default => 0, :null => false + t.string "property", :limit => 30, :default => "", :null => false + t.string "prop_key", :limit => 30, :default => "", :null => false + t.text "old_value" + t.text "value" + end + + add_index "journal_details", ["journal_id"], :name => "journal_details_journal_id" + + create_table "journal_replies", :id => false, :force => true do |t| + t.integer "journal_id" + t.integer "user_id" + t.integer "reply_id" + end + + add_index "journal_replies", ["journal_id"], :name => "index_journal_replies_on_journal_id" + add_index "journal_replies", ["reply_id"], :name => "index_journal_replies_on_reply_id" + add_index "journal_replies", ["user_id"], :name => "index_journal_replies_on_user_id" + + create_table "journals", :force => true do |t| + t.integer "journalized_id", :default => 0, :null => false + t.string "journalized_type", :limit => 30, :default => "", :null => false + t.integer "user_id", :default => 0, :null => false + t.text "notes" + t.datetime "created_on", :null => false + t.boolean "private_notes", :default => false, :null => false + t.integer "parent_id" + t.integer "comments_count", :default => 0 + t.integer "reply_id" + end + + add_index "journals", ["created_on"], :name => "index_journals_on_created_on" + add_index "journals", ["journalized_id", "journalized_type"], :name => "journals_journalized_id" + add_index "journals", ["journalized_id"], :name => "index_journals_on_journalized_id" + add_index "journals", ["user_id"], :name => "index_journals_on_user_id" + + create_table "journals_for_messages", :force => true do |t| + t.integer "jour_id" + t.string "jour_type" + t.integer "user_id" + t.text "notes" + t.integer "status" + t.integer "reply_id" + t.datetime "created_on", :null => false + t.datetime "updated_on", :null => false + t.string "m_parent_id" + t.boolean "is_readed" + t.integer "m_reply_count" + t.integer "m_reply_id" + t.integer "is_comprehensive_evaluation" + t.integer "private", :default => 0 + end + + create_table "kindeditor_assets", :force => true do |t| + t.string "asset" + t.integer "file_size" + t.string "file_type" + t.integer "owner_id" + t.string "asset_type" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "owner_type", :default => 0 + end + + create_table "member_roles", :force => true do |t| + t.integer "member_id", :null => false + t.integer "role_id", :null => false + t.integer "inherited_from" + t.integer "is_current", :default => 1 + end + + add_index "member_roles", ["member_id"], :name => "index_member_roles_on_member_id" + add_index "member_roles", ["role_id"], :name => "index_member_roles_on_role_id" + + create_table "members", :force => true do |t| + t.integer "user_id", :default => 0, :null => false + t.integer "project_id", :default => 0 + t.datetime "created_on" + t.boolean "mail_notification", :default => false, :null => false + t.integer "course_id", :default => -1 + t.integer "course_group_id", :default => 0 + end + + add_index "members", ["project_id"], :name => "index_members_on_project_id" + add_index "members", ["user_id", "project_id", "course_id"], :name => "index_members_on_user_id_and_project_id", :unique => true + add_index "members", ["user_id"], :name => "index_members_on_user_id" + + create_table "memo_messages", :force => true do |t| + t.integer "user_id" + t.integer "forum_id" + t.integer "memo_id" + t.string "memo_type" + t.integer "viewed" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "memo_messages", ["memo_id", "memo_type"], :name => "index_memo_messages_on_memo_id_and_memo_type" + add_index "memo_messages", ["user_id", "forum_id", "created_at"], :name => "index_memo_messages_on_user_id_and_forum_id_and_created_at" + + create_table "memos", :force => true do |t| + t.integer "forum_id", :null => false + t.integer "parent_id" + t.string "subject", :null => false + t.text "content", :null => false + t.integer "author_id", :null => false + t.integer "replies_count", :default => 0 + t.integer "last_reply_id" + t.boolean "lock", :default => false + t.boolean "sticky", :default => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "viewed_count", :default => 0 + end + + create_table "message_alls", :force => true do |t| + t.integer "user_id" + t.integer "message_id" + t.string "message_type" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "message_alls", ["message_type"], :name => "index_message_alls_on_message_type" + add_index "message_alls", ["user_id", "message_id", "created_at"], :name => "index_message_alls_on_user_id_and_message_id_and_created_at" + + create_table "messages", :force => true do |t| + t.integer "board_id", :null => false + t.integer "parent_id" + t.string "subject", :default => "", :null => false + t.text "content" + t.integer "author_id" + t.integer "replies_count", :default => 0, :null => false + t.integer "last_reply_id" + t.datetime "created_on", :null => false + t.datetime "updated_on", :null => false + t.boolean "locked", :default => false + t.integer "sticky", :default => 0 + t.integer "reply_id" + t.integer "quotes" + t.integer "status", :default => 0 + end + + add_index "messages", ["author_id"], :name => "index_messages_on_author_id" + add_index "messages", ["board_id"], :name => "messages_board_id" + add_index "messages", ["created_on"], :name => "index_messages_on_created_on" + add_index "messages", ["last_reply_id"], :name => "index_messages_on_last_reply_id" + add_index "messages", ["parent_id"], :name => "messages_parent_id" + + create_table "news", :force => true do |t| + t.integer "project_id" + t.string "title", :limit => 60, :default => "", :null => false + t.string "summary", :default => "" + t.text "description" + t.integer "author_id", :default => 0, :null => false + t.datetime "created_on" + t.integer "comments_count", :default => 0, :null => false + t.integer "course_id" + t.integer "sticky", :default => 0 + t.integer "org_subfield_id" + end + + add_index "news", ["author_id"], :name => "index_news_on_author_id" + add_index "news", ["created_on"], :name => "index_news_on_created_on" + add_index "news", ["project_id"], :name => "news_project_id" + + create_table "no_uses", :force => true do |t| + t.integer "user_id", :null => false + t.string "no_use_type" + t.integer "no_use_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "notificationcomments", :force => true do |t| + t.string "notificationcommented_type" + t.integer "notificationcommented_id" + t.integer "author_id" + t.text "notificationcomments" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "onclick_times", :force => true do |t| + t.integer "user_id" + t.datetime "onclick_time" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "open_id_authentication_associations", :force => true do |t| + t.integer "issued" + t.integer "lifetime" + t.string "handle" + t.string "assoc_type" + t.binary "server_url" + t.binary "secret" + end + + create_table "open_id_authentication_nonces", :force => true do |t| + t.integer "timestamp", :null => false + t.string "server_url" + t.string "salt", :null => false + end + + create_table "open_source_projects", :force => true do |t| + t.string "name" + t.text "description" + t.integer "commit_count", :default => 0 + t.integer "code_line", :default => 0 + t.integer "users_count", :default => 0 + t.date "last_commit_time" + t.string "url" + t.date "date_collected" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "option_numbers", :force => true do |t| + t.integer "user_id" + t.integer "memo" + t.integer "messages_for_issues" + t.integer "issues_status" + t.integer "replay_for_message" + t.integer "replay_for_memo" + t.integer "follow" + t.integer "tread" + t.integer "praise_by_one" + t.integer "praise_by_two" + t.integer "praise_by_three" + t.integer "tread_by_one" + t.integer "tread_by_two" + t.integer "tread_by_three" + t.integer "changeset" + t.integer "document" + t.integer "attachment" + t.integer "issue_done_ratio" + t.integer "post_issue" + t.integer "score_type" + t.integer "total_score" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "project_id" + end + + create_table "org_activities", :force => true do |t| + t.integer "user_id" + t.integer "org_act_id" + t.string "org_act_type" + t.integer "container_id" + t.string "container_type" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "org_courses", :force => true do |t| + t.integer "organization_id" + t.integer "course_id" + t.datetime "created_at" + end + + create_table "org_document_comments", :force => true do |t| + t.text "title" + t.text "content" + t.integer "organization_id" + t.integer "creator_id" + t.integer "parent_id" + t.integer "reply_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.boolean "locked", :default => false + t.integer "sticky", :default => 0 + t.integer "org_subfield_id" + t.integer "status", :default => 0 + end + + create_table "org_member_roles", :force => true do |t| + t.integer "org_member_id" + t.integer "role_id" + end + + create_table "org_members", :force => true do |t| + t.integer "user_id" + t.integer "organization_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "org_messages", :force => true do |t| + t.integer "user_id" + t.integer "sender_id" + t.integer "organization_id" + t.string "message_type" + t.integer "message_id" + t.integer "viewed" + t.string "content" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "status", :default => 0 + end + + create_table "org_projects", :force => true do |t| + t.integer "organization_id" + t.integer "project_id" + t.datetime "created_at" + end + + create_table "org_subfield_messages", :force => true do |t| + t.integer "org_subfield_id" + t.integer "message_id" + t.string "message_type" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "org_subfields", :force => true do |t| + t.integer "organization_id" + t.integer "priority" + t.string "name" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "field_type" + t.integer "hide", :default => 0 + t.integer "status", :default => 1 + end + + create_table "organizations", :force => true do |t| + t.string "name" + t.text "description" + t.integer "creator_id" + t.integer "home_id" + t.boolean "is_public" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.boolean "allow_guest_download", :default => true + t.integer "visits", :default => 0 + t.integer "show_mode", :default => 0 + t.integer "allow_teacher", :default => 0 + end + + create_table "phone_app_versions", :force => true do |t| + t.string "version" + t.text "description" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "poll_answers", :force => true do |t| + t.integer "poll_question_id" + t.text "answer_text" + t.integer "answer_position" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "poll_questions", :force => true do |t| + t.string "question_title" + t.integer "question_type" + t.integer "is_necessary" + t.integer "poll_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "question_number" + end + + create_table "poll_users", :force => true do |t| + t.integer "user_id" + t.integer "poll_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "poll_votes", :force => true do |t| + t.integer "user_id" + t.integer "poll_question_id" + t.integer "poll_answer_id" + t.text "vote_text" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "polls", :force => true do |t| + t.string "polls_name" + t.string "polls_type" + t.integer "polls_group_id" + t.integer "polls_status" + t.integer "user_id" + t.datetime "published_at" + t.datetime "closed_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.text "polls_description" + t.integer "show_result", :default => 1 + end + + create_table "praise_tread_caches", :force => true do |t| + t.integer "object_id", :null => false + t.string "object_type" + t.integer "praise_num" + t.integer "tread_num" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "praise_treads", :force => true do |t| + t.integer "user_id", :null => false + t.integer "praise_tread_object_id" + t.string "praise_tread_object_type" + t.integer "praise_or_tread" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "principal_activities", :force => true do |t| + t.integer "user_id" + t.integer "principal_id" + t.integer "principal_act_id" + t.string "principal_act_type" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "project_infos", :force => true do |t| + t.integer "project_id" + t.integer "user_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "project_scores", :force => true do |t| + t.string "project_id" + t.integer "score" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "issue_num", :default => 0 + t.integer "issue_journal_num", :default => 0 + t.integer "news_num", :default => 0 + t.integer "documents_num", :default => 0 + t.integer "changeset_num", :default => 0 + t.integer "board_message_num", :default => 0 + t.integer "board_num", :default => 0 + t.integer "attach_num", :default => 0 + t.datetime "commit_time" + end + + create_table "project_statuses", :force => true do |t| + t.integer "changesets_count" + t.integer "watchers_count" + t.integer "project_id" + t.integer "project_type" + t.float "grade", :default => 0.0 + t.integer "course_ac_para", :default => 0 + end + + add_index "project_statuses", ["grade"], :name => "index_project_statuses_on_grade" + + create_table "projecting_softapplictions", :force => true do |t| + t.integer "user_id" + t.integer "softapplication_id" + t.integer "project_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "projects", :force => true do |t| + t.string "name", :default => "", :null => false + t.text "description" + t.string "homepage", :default => "" + t.boolean "is_public", :default => true, :null => false + t.integer "parent_id" + t.datetime "created_on" + t.datetime "updated_on" + t.string "identifier" + t.integer "status", :default => 1, :null => false + t.integer "lft" + t.integer "rgt" + t.boolean "inherit_members", :default => false, :null => false + t.integer "project_type" + t.boolean "hidden_repo", :default => false, :null => false + t.integer "attachmenttype", :default => 1 + t.integer "user_id" + t.integer "dts_test", :default => 0 + t.string "enterprise_name" + t.integer "organization_id" + t.integer "project_new_type" + t.integer "gpid" + t.integer "forked_from_project_id" + t.integer "forked_count" + t.integer "commits_count", :default => 0 + t.integer "publish_resource", :default => 0 + t.integer "issues_count", :default => 0 + t.integer "attachments_count", :default => 0 + t.integer "boards_count", :default => 0 + t.integer "news_count", :default => 0 + t.integer "acts_count", :default => 0 + t.integer "journals_count", :default => 0 + t.integer "boards_reply_count", :default => 0 + t.integer "visits", :default => 0 + t.integer "hot", :default => 0 + t.string "invite_code" + t.string "qrcode" + end + + add_index "projects", ["lft"], :name => "index_projects_on_lft" + add_index "projects", ["rgt"], :name => "index_projects_on_rgt" + + create_table "projects_trackers", :id => false, :force => true do |t| + t.integer "project_id", :default => 0, :null => false + t.integer "tracker_id", :default => 0, :null => false + end + + add_index "projects_trackers", ["project_id", "tracker_id"], :name => "projects_trackers_unique", :unique => true + add_index "projects_trackers", ["project_id"], :name => "projects_trackers_project_id" + + create_table "quality_analyses", :force => true do |t| + t.integer "project_id" + t.string "author_login" + t.string "rep_identifier" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "sonar_version", :default => 0 + t.string "path" + t.string "branch" + t.string "language" + t.string "sonar_name" + end + + create_table "queries", :force => true do |t| + t.integer "project_id" + t.string "name", :default => "", :null => false + t.text "filters" + t.integer "user_id", :default => 0, :null => false + t.boolean "is_public", :default => false, :null => false + t.text "column_names" + t.text "sort_criteria" + t.string "group_by" + t.string "type" + end + + add_index "queries", ["project_id"], :name => "index_queries_on_project_id" + add_index "queries", ["user_id"], :name => "index_queries_on_user_id" + + create_table "relative_memo_to_open_source_projects", :force => true do |t| + t.integer "osp_id" + t.integer "relative_memo_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "relative_memos", :force => true do |t| + t.integer "osp_id" + t.integer "parent_id" + t.string "subject", :null => false + t.text "content", :limit => 16777215, :null => false + t.integer "author_id" + t.integer "replies_count", :default => 0 + t.integer "last_reply_id" + t.boolean "lock", :default => false + t.boolean "sticky", :default => false + t.boolean "is_quote", :default => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "viewed_count_crawl", :default => 0 + t.integer "viewed_count_local", :default => 0 + t.string "url" + t.string "username" + t.string "userhomeurl" + t.date "date_collected" + t.string "topic_resource" + end + + create_table "rep_statics", :force => true do |t| + t.integer "project_id" + t.integer "commits_num" + t.string "uname" + t.string "email" + t.integer "add" + t.integer "del" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "changeset" + end + + create_table "repositories", :force => true do |t| + t.integer "project_id", :default => 0, :null => false + t.string "url", :default => "", :null => false + t.string "login", :limit => 60, :default => "" + t.string "password", :default => "" + t.string "root_url", :default => "" + t.string "type" + t.string "path_encoding", :limit => 64 + t.string "log_encoding", :limit => 64 + t.text "extra_info" + t.string "identifier" + t.boolean "is_default", :default => false + t.boolean "hidden", :default => false + end + + add_index "repositories", ["project_id"], :name => "index_repositories_on_project_id" + + create_table "rich_rich_files", :force => true do |t| + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "rich_file_file_name" + t.string "rich_file_content_type" + t.integer "rich_file_file_size" + t.datetime "rich_file_updated_at" + t.string "owner_type" + t.integer "owner_id" + t.text "uri_cache" + t.string "simplified_type", :default => "file" + end + + create_table "roles", :force => true do |t| + t.string "name", :limit => 30, :default => "", :null => false + t.integer "position", :default => 1 + t.boolean "assignable", :default => true + t.integer "builtin", :default => 0, :null => false + t.text "permissions" + t.string "issues_visibility", :limit => 30, :default => "default", :null => false + end + + create_table "schools", :force => true do |t| + t.string "name" + t.string "province" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "logo_link" + t.string "pinyin" + t.integer "school_type", :default => 0 + end + + create_table "secdomains", :force => true do |t| + t.integer "sub_type" + t.string "subname" + t.integer "pid", :default => 0 + t.string "desc" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "seems_rateable_cached_ratings", :force => true do |t| + t.integer "cacheable_id", :limit => 8 + t.string "cacheable_type" + t.float "avg", :null => false + t.integer "cnt", :null => false + t.string "dimension" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "seems_rateable_rates", :force => true do |t| + t.integer "rater_id", :limit => 8 + t.integer "rateable_id" + t.string "rateable_type" + t.float "stars", :null => false + t.string "dimension" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "is_teacher_score", :default => 0 + end + + create_table "settings", :force => true do |t| + t.string "name", :default => "", :null => false + t.text "value" + t.datetime "updated_on" + end + + add_index "settings", ["name"], :name => "index_settings_on_name" + + create_table "shares", :force => true do |t| + t.date "created_on" + t.string "url" + t.string "title" + t.integer "share_type" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "project_id" + t.integer "user_id" + t.string "description" + end + + create_table "shield_activities", :force => true do |t| + t.string "container_type" + t.integer "container_id" + t.string "shield_type" + t.integer "shield_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "shield_wechat_messages", :force => true do |t| + t.integer "container_id" + t.string "container_type" + t.integer "shield_id" + t.string "shield_type" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "softapplications", :force => true do |t| + t.string "name" + t.text "description" + t.integer "app_type_id" + t.string "app_type_name" + t.string "android_min_version_available" + t.integer "user_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "contest_id" + t.integer "softapplication_id" + t.integer "is_public" + t.string "application_developers" + t.string "deposit_project_url" + t.string "deposit_project" + t.integer "project_id" + end + + create_table "sonar_errors", :force => true do |t| + t.integer "project_id" + t.string "jenkins_job_name" + t.text "output" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "ssos", :force => true do |t| + t.integer "user_id" + t.string "openid" + t.string "name" + t.string "password" + t.string "email" + t.integer "sex" + t.string "school" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "ssos", ["user_id"], :name => "index_ssos_on_user_id" + + create_table "student_work_projects", :force => true do |t| + t.integer "homework_common_id" + t.integer "student_work_id" + t.integer "project_id" + t.integer "user_id" + t.integer "is_leader" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "student_work_projects", ["homework_common_id"], :name => "index_student_work_projects_on_homework_common_id" + add_index "student_work_projects", ["project_id"], :name => "index_student_work_projects_on_project_id" + add_index "student_work_projects", ["student_work_id"], :name => "index_student_work_projects_on_student_work_id" + add_index "student_work_projects", ["user_id"], :name => "index_student_work_projects_on_user_id" + + create_table "student_work_tests", :force => true do |t| + t.integer "student_work_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "status", :default => 9 + t.text "results" + t.text "src" + end + + create_table "student_works", :force => true do |t| + t.string "name" + t.text "description", :limit => 2147483647 + t.integer "homework_common_id" + t.integer "user_id" + t.float "final_score" + t.float "teacher_score" + t.float "student_score" + t.float "teaching_asistant_score" + t.integer "project_id", :default => 0 + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "late_penalty", :default => 0 + t.integer "absence_penalty", :default => 0 + t.float "system_score", :default => 0.0 + t.boolean "is_test", :default => false + t.integer "simi_id" + t.integer "simi_value" + t.float "work_score" + t.integer "work_status", :default => 0 + end + + add_index "student_works", ["homework_common_id", "user_id"], :name => "index_student_works_on_homework_common_id_and_user_id" + + create_table "student_works_evaluation_distributions", :force => true do |t| + t.integer "student_work_id" + t.integer "user_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "student_works_scores", :force => true do |t| + t.integer "student_work_id" + t.integer "user_id" + t.integer "score" + t.text "comment" + t.integer "reviewer_role" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "students_for_courses", :force => true do |t| + t.integer "student_id" + t.integer "course_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "students_for_courses", ["course_id"], :name => "index_students_for_courses_on_course_id" + add_index "students_for_courses", ["student_id"], :name => "index_students_for_courses_on_student_id" + + create_table "sub_document_comments", :force => true do |t| + t.text "content" + t.text "title" + t.integer "sub_domain_id" + t.integer "creator_id" + t.integer "parent_id" + t.integer "reply_id" + t.integer "locked" + t.integer "sticky" + t.integer "org_subfield_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "sub_domains", :force => true do |t| + t.integer "org_subfield_id" + t.integer "priority", :default => 0 + t.string "name" + t.string "field_type" + t.integer "hide", :default => 0 + t.integer "status", :default => 0 + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "subfield_subdomain_dirs", :force => true do |t| + t.integer "org_subfield_id" + t.string "name" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "syllabuses", :force => true do |t| + t.string "title" + t.text "description" + t.integer "user_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "eng_name" + t.integer "syllabus_type" + t.integer "credit" + t.integer "hours" + t.integer "theory_hours" + t.integer "practice_hours" + t.string "applicable_major" + t.string "pre_course" + t.integer "visits", :default => 0 + t.integer "des_status", :default => 0 + end + + add_index "syllabuses", ["user_id"], :name => "index_syllabuses_on_user_id" + + create_table "system_messages", :force => true do |t| + t.integer "user_id" + t.string "content" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.text "description" + t.string "subject" + end + + create_table "taggings", :force => true do |t| + t.integer "tag_id" + t.integer "taggable_id" + t.string "taggable_type" + t.integer "tagger_id" + t.string "tagger_type" + t.string "context", :limit => 128 + t.datetime "created_at" + end + + add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id" + add_index "taggings", ["taggable_id", "taggable_type", "context"], :name => "index_taggings_on_taggable_id_and_taggable_type_and_context" + add_index "taggings", ["taggable_type"], :name => "index_taggings_on_taggable_type" + + create_table "tags", :force => true do |t| + t.string "name" + end + + create_table "teachers", :force => true do |t| + t.string "tea_name" + t.string "location" + t.integer "couurse_time" + t.integer "course_code" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "extra" + end + + create_table "time_entries", :force => true do |t| + t.integer "project_id", :null => false + t.integer "user_id", :null => false + t.integer "issue_id" + t.float "hours", :null => false + t.string "comments" + t.integer "activity_id", :null => false + t.date "spent_on", :null => false + t.integer "tyear", :null => false + t.integer "tmonth", :null => false + t.integer "tweek", :null => false + t.datetime "created_on", :null => false + t.datetime "updated_on", :null => false + end + + add_index "time_entries", ["activity_id"], :name => "index_time_entries_on_activity_id" + add_index "time_entries", ["created_on"], :name => "index_time_entries_on_created_on" + add_index "time_entries", ["issue_id"], :name => "time_entries_issue_id" + add_index "time_entries", ["project_id"], :name => "time_entries_project_id" + add_index "time_entries", ["user_id"], :name => "index_time_entries_on_user_id" + + create_table "tokens", :force => true do |t| + t.integer "user_id", :default => 0, :null => false + t.string "action", :limit => 30, :default => "", :null => false + t.string "value", :limit => 40, :default => "", :null => false + t.datetime "created_on", :null => false + end + + add_index "tokens", ["user_id"], :name => "index_tokens_on_user_id" + add_index "tokens", ["value"], :name => "tokens_value", :unique => true + + create_table "trackers", :force => true do |t| + t.string "name", :limit => 30, :default => "", :null => false + t.boolean "is_in_chlog", :default => false, :null => false + t.integer "position", :default => 1 + t.boolean "is_in_roadmap", :default => true, :null => false + t.integer "fields_bits", :default => 0 + end + + create_table "user_actions", :force => true do |t| + t.integer "user_id" + t.string "action_type" + t.integer "action_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "user_activities", :force => true do |t| + t.string "act_type" + t.integer "act_id" + t.string "container_type" + t.integer "container_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "user_id" + end + + add_index "user_activities", ["act_id", "act_type", "container_id", "created_at"], :name => "user_act_index" + + create_table "user_extensions", :force => true do |t| + t.integer "user_id", :null => false + t.date "birthday" + t.string "brief_introduction" + t.integer "gender" + t.string "location" + t.string "occupation" + t.integer "work_experience" + t.integer "zip_code" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "technical_title" + t.integer "identity" + t.string "student_id" + t.string "teacher_realname" + t.string "student_realname" + t.string "location_city" + t.integer "school_id" + t.string "description", :default => "" + end + + create_table "user_feedback_messages", :force => true do |t| + t.integer "user_id" + t.integer "journals_for_message_id" + t.string "journals_for_message_type" + t.integer "viewed" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "user_feedback_messages", ["journals_for_message_id"], :name => "index_user_feedback_messages_on_journals_for_message_id" + add_index "user_feedback_messages", ["user_id", "created_at"], :name => "index_user_feedback_messages_on_user_id_and_created_at" + + create_table "user_grades", :force => true do |t| + t.integer "user_id", :null => false + t.integer "project_id", :null => false + t.float "grade", :default => 0.0 + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "user_grades", ["grade"], :name => "index_user_grades_on_grade" + add_index "user_grades", ["project_id"], :name => "index_user_grades_on_project_id" + add_index "user_grades", ["user_id"], :name => "index_user_grades_on_user_id" + + create_table "user_levels", :force => true do |t| + t.integer "user_id" + t.integer "level" + end + + create_table "user_preferences", :force => true do |t| + t.integer "user_id", :default => 0, :null => false + t.text "others" + t.boolean "hide_mail", :default => false + t.string "time_zone" + end + + add_index "user_preferences", ["user_id"], :name => "index_user_preferences_on_user_id" + + create_table "user_score_details", :force => true do |t| + t.integer "current_user_id" + t.integer "target_user_id" + t.string "score_type" + t.string "score_action" + t.integer "user_id" + t.integer "old_score" + t.integer "new_score" + t.integer "current_user_level" + t.integer "target_user_level" + t.integer "score_changeable_obj_id" + t.string "score_changeable_obj_type" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "user_scores", :force => true do |t| + t.integer "user_id", :null => false + t.integer "collaboration" + t.integer "influence" + t.integer "skill" + t.integer "active" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "user_statuses", :force => true do |t| + t.integer "changesets_count" + t.integer "watchers_count" + t.integer "user_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.float "grade", :default => 0.0 + end + + add_index "user_statuses", ["changesets_count"], :name => "index_user_statuses_on_changesets_count" + add_index "user_statuses", ["grade"], :name => "index_user_statuses_on_grade" + add_index "user_statuses", ["watchers_count"], :name => "index_user_statuses_on_watchers_count" + + create_table "user_wechats", :force => true do |t| + t.integer "subscribe" + t.string "openid" + t.string "nickname" + t.integer "sex" + t.string "language" + t.string "city" + t.string "province" + t.string "country" + t.string "headimgurl" + t.string "subscribe_time" + t.string "unionid" + t.string "remark" + t.integer "groupid" + t.integer "user_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "users", :force => true do |t| + t.string "login", :default => "", :null => false + t.string "hashed_password", :limit => 40, :default => "", :null => false + t.string "firstname", :limit => 30, :default => "", :null => false + t.string "lastname", :default => "", :null => false + t.string "mail", :limit => 60, :default => "", :null => false + t.boolean "admin", :default => false, :null => false + t.integer "status", :default => 1, :null => false + t.datetime "last_login_on" + t.string "language", :limit => 5, :default => "" + t.integer "auth_source_id" + t.datetime "created_on" + t.datetime "updated_on" + t.string "type" + t.string "identity_url" + t.string "mail_notification", :default => "", :null => false + t.string "salt", :limit => 64 + t.integer "gid" + t.integer "visits", :default => 0 + t.integer "excellent_teacher", :default => 0 + t.integer "excellent_student", :default => 0 + end + + add_index "users", ["auth_source_id"], :name => "index_users_on_auth_source_id" + add_index "users", ["id", "type"], :name => "index_users_on_id_and_type" + add_index "users", ["type"], :name => "index_users_on_type" + + create_table "versions", :force => true do |t| + t.integer "project_id", :default => 0, :null => false + t.string "name", :default => "", :null => false + t.string "description", :default => "" + t.date "effective_date" + t.datetime "created_on" + t.datetime "updated_on" + t.string "wiki_page_title" + t.string "status", :default => "open" + t.string "sharing", :default => "none", :null => false + end + + add_index "versions", ["project_id"], :name => "versions_project_id" + add_index "versions", ["sharing"], :name => "index_versions_on_sharing" + + create_table "visitors", :force => true do |t| + t.integer "user_id" + t.integer "master_id" + t.datetime "updated_on" + t.datetime "created_on" + end + + add_index "visitors", ["master_id"], :name => "index_visitors_master_id" + add_index "visitors", ["updated_on"], :name => "index_visitors_updated_on" + add_index "visitors", ["user_id"], :name => "index_visitors_user_id" + + create_table "watchers", :force => true do |t| + t.string "watchable_type", :default => "", :null => false + t.integer "watchable_id", :default => 0, :null => false + t.integer "user_id" + end + + add_index "watchers", ["user_id", "watchable_type"], :name => "watchers_user_id_type" + add_index "watchers", ["user_id"], :name => "index_watchers_on_user_id" + add_index "watchers", ["watchable_id", "watchable_type"], :name => "index_watchers_on_watchable_id_and_watchable_type" + + create_table "web_footer_companies", :force => true do |t| + t.string "name" + t.string "logo_size" + t.string "url" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "web_footer_oranizers", :force => true do |t| + t.string "name" + t.text "description" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "wechat_logs", :force => true do |t| + t.string "openid", :null => false + t.text "request_raw" + t.text "response_raw" + t.text "session_raw" + t.datetime "created_at", :null => false + end + + add_index "wechat_logs", ["openid"], :name => "index_wechat_logs_on_openid" + + create_table "wiki_content_versions", :force => true do |t| + t.integer "wiki_content_id", :null => false + t.integer "page_id", :null => false + t.integer "author_id" + t.binary "data", :limit => 2147483647 + t.string "compression", :limit => 6, :default => "" + t.string "comments", :default => "" + t.datetime "updated_on", :null => false + t.integer "version", :null => false + end + + add_index "wiki_content_versions", ["updated_on"], :name => "index_wiki_content_versions_on_updated_on" + add_index "wiki_content_versions", ["wiki_content_id"], :name => "wiki_content_versions_wcid" + + create_table "wiki_contents", :force => true do |t| + t.integer "page_id", :null => false + t.integer "author_id" + t.text "text", :limit => 2147483647 + t.string "comments", :default => "" + t.datetime "updated_on", :null => false + t.integer "version", :null => false + end + + add_index "wiki_contents", ["author_id"], :name => "index_wiki_contents_on_author_id" + add_index "wiki_contents", ["page_id"], :name => "wiki_contents_page_id" + + create_table "wiki_pages", :force => true do |t| + t.integer "wiki_id", :null => false + t.string "title", :null => false + t.datetime "created_on", :null => false + t.boolean "protected", :default => false, :null => false + t.integer "parent_id" + end + + add_index "wiki_pages", ["parent_id"], :name => "index_wiki_pages_on_parent_id" + add_index "wiki_pages", ["wiki_id", "title"], :name => "wiki_pages_wiki_id_title" + add_index "wiki_pages", ["wiki_id"], :name => "index_wiki_pages_on_wiki_id" + + create_table "wiki_redirects", :force => true do |t| + t.integer "wiki_id", :null => false + t.string "title" + t.string "redirects_to" + t.datetime "created_on", :null => false + end + + add_index "wiki_redirects", ["wiki_id", "title"], :name => "wiki_redirects_wiki_id_title" + add_index "wiki_redirects", ["wiki_id"], :name => "index_wiki_redirects_on_wiki_id" + + create_table "wikis", :force => true do |t| + t.integer "project_id", :null => false + t.string "start_page", :null => false + t.integer "status", :default => 1, :null => false + end + + add_index "wikis", ["project_id"], :name => "wikis_project_id" + + create_table "workflows", :force => true do |t| + t.integer "tracker_id", :default => 0, :null => false + t.integer "old_status_id", :default => 0, :null => false + t.integer "new_status_id", :default => 0, :null => false + t.integer "role_id", :default => 0, :null => false + t.boolean "assignee", :default => false, :null => false + t.boolean "author", :default => false, :null => false + t.string "type", :limit => 30 + t.string "field_name", :limit => 30 + t.string "rule", :limit => 30 + end + + add_index "workflows", ["new_status_id"], :name => "index_workflows_on_new_status_id" + add_index "workflows", ["old_status_id"], :name => "index_workflows_on_old_status_id" + add_index "workflows", ["role_id", "tracker_id", "old_status_id"], :name => "wkfs_role_tracker_old_status" + add_index "workflows", ["role_id"], :name => "index_workflows_on_role_id" + + create_table "works_categories", :force => true do |t| + t.string "category" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "zip_packs", :force => true do |t| + t.integer "user_id" + t.integer "homework_id" + t.string "file_digest" + t.string "file_path" + t.integer "pack_times", :default => 1 + t.integer "pack_size", :default => 0 + t.text "file_digests" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + +end diff --git a/public/javascripts/application.js b/public/javascripts/application.js index 9841a20a7..3ea266a9a 100644 --- a/public/javascripts/application.js +++ b/public/javascripts/application.js @@ -1493,13 +1493,18 @@ function pop_up_box(value,tWidth,tTop,tLeft){ } // 公共弹框样式 -function pop_box_new(value, Width, Top, Left){ +function pop_box_new(value, Width, Height){ + w = ($(window).width() - Width)/2; + h = ($(window).height() - Height)/2; $("#ajax-modal").html(value); showModal('ajax-modal', Width + 'px'); $('#ajax-modal').siblings().remove(); - $('#ajax-modal').parent().css({"top": Top+"%","left": Left+"%","transform":"translate(-50%,-50%)","padding":"0","border":"none"}); + $('#ajax-modal').parent().css({"top": h+"px","left": w+"px","padding":"0","border":"none","position":"fixed"}); $('#ajax-modal').css({"padding":"0"}); + //拖拽 + $ + } // 公共提示弹框样式 From f016027e8fd5b4e131908e22648349e468e26cb5 Mon Sep 17 00:00:00 2001 From: yuanke <249218296@qq.com> Date: Mon, 1 Aug 2016 15:35:29 +0800 Subject: [PATCH 15/78] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E5=8A=A0=E5=85=A5?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/wechats_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/wechats_controller.rb b/app/controllers/wechats_controller.rb index 118aea0f2..9afca5c3a 100644 --- a/app/controllers/wechats_controller.rb +++ b/app/controllers/wechats_controller.rb @@ -237,7 +237,7 @@ class WechatsController < ActionController::Base end end - raise "该二维码已失效!" + raise "该二维码已失效" rescue => e logger.error e.inspect @@ -313,7 +313,7 @@ class WechatsController < ActionController::Base ps = ProjectsService.new status = ps.join_project({invite_code: project.invite_code}, user) - if status[:state] != 0 + if status != 0 raise ProjectsService::JoinProjectError.message(status) end From fc1fc0bd7d45aaa78f4037386f758ba0a43ad27d Mon Sep 17 00:00:00 2001 From: daiao <358551898@qq.com> Date: Mon, 1 Aug 2016 15:44:18 +0800 Subject: [PATCH 16/78] =?UTF-8?q?=E5=8D=95=E4=BD=8D=E5=AE=A1=E6=A0=B8bug?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/admin_controller.rb | 14 ++++++++++---- app/controllers/school_controller.rb | 2 +- app/models/apply_add_schools.rb | 10 +--------- app/views/admin/applied_schools.html.erb | 6 +++--- app/views/admin/has_applied_schools.html.erb | 4 ++-- app/views/users/_user_message_applied.html.erb | 6 +++--- 6 files changed, 20 insertions(+), 22 deletions(-) diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb index 060f23ec4..8f1504a4b 100644 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/admin_controller.rb @@ -713,17 +713,23 @@ class AdminController < ApplicationController def delete_applied_schools applied_school = ApplyAddSchools.find(params[:id]) applied_school.update_attribute(:status, 3) + # 未审批删除 + if params[:tip] == "unapplied" AppliedMessage.create(:user_id => applied_school.user_id, :status => 3, :viewed => true, :applied_id => applied_school.id, :applied_type => "ApplyAddSchools", :name => applied_school.name ) + # 删除学校的用户 users = UserExtensions.where("school_id = #{applied_school.school_id}") users.each do |user| user.update_column("school_id", nil) end - applied_school.school.destroy - - # 跳转当前页面 - if params[:tip] == "unapplied" + applied_school.school.destroy redirect_to unapplied_schools_url + # 已审批删除 elsif params[:tip] == "applied" + users = UserExtensions.where("school_id = #{applied_school.school_id}") + users.each do |user| + user.update_column("school_id", nil) + end + applied_school.destroy redirect_to applied_schools_url end end diff --git a/app/controllers/school_controller.rb b/app/controllers/school_controller.rb index 76d149f94..98d814137 100644 --- a/app/controllers/school_controller.rb +++ b/app/controllers/school_controller.rb @@ -191,7 +191,7 @@ class SchoolController < ApplicationController # status=4 向管理员发送信息 users = User.where(:admin => 1) users.each do |user| - AppliedMessage.create(:user_id => user.id, :status => 4, :applied_user_id => User.current.id, :viewed => true, :applied_id => school.id, :applied_type => "ApplyAddSchools", :name => school.name ) + AppliedMessage.create(:user_id => user.id, :status => 0, :applied_user_id => User.current.id, :viewed => true, :applied_id => school.id, :applied_type => "ApplyAddSchools", :name => school.name ) end else data[:result] = 3 diff --git a/app/models/apply_add_schools.rb b/app/models/apply_add_schools.rb index 573a494ef..60c2c404f 100644 --- a/app/models/apply_add_schools.rb +++ b/app/models/apply_add_schools.rb @@ -4,13 +4,5 @@ class ApplyAddSchools < ActiveRecord::Base has_many :applied_messages, :class_name =>'AppliedMessage', :as => :applied belongs_to :school - after_create :send_massage - - #给系统所有管理发送消息 - def send_massage - users = User.where(:admin => 1) - users.each do |user| - self.applied_messages << AppliedMessage.new(:user_id => user.id, :viewed => false, :status => false) - end - end + #after_create :send_massage end diff --git a/app/views/admin/applied_schools.html.erb b/app/views/admin/applied_schools.html.erb index 2f139ca72..6c739cfb3 100644 --- a/app/views/admin/applied_schools.html.erb +++ b/app/views/admin/applied_schools.html.erb @@ -29,7 +29,7 @@ 申请者 - + 地区 @@ -67,7 +67,7 @@ <%= (apply.province.nil? ? "" : apply.province) + (apply.city.nil? ? "" : apply.city) %> - @@ -104,7 +104,7 @@ - + <%= apply.address %> diff --git a/app/views/admin/has_applied_schools.html.erb b/app/views/admin/has_applied_schools.html.erb index 1b6341fb3..5b45c65ca 100644 --- a/app/views/admin/has_applied_schools.html.erb +++ b/app/views/admin/has_applied_schools.html.erb @@ -73,7 +73,7 @@ <%= (apply.province.nil? ? "" : apply.province) + (apply.city.nil? ? "" : apply.city) %> - @@ -110,7 +110,7 @@ - + <%= apply.address %> diff --git a/app/views/users/_user_message_applied.html.erb b/app/views/users/_user_message_applied.html.erb index fbe422242..dbe01c4b4 100644 --- a/app/views/users/_user_message_applied.html.erb +++ b/app/views/users/_user_message_applied.html.erb @@ -1,13 +1,13 @@ <% if ma.class == AppliedMessage %> <% if ma.applied_type == "ApplyAddSchools" %> - <% if ma.status == 1 || ma.status == 2 || ma.status == 3 || ma.status == 4 %> + <% if ma.status == 1 || ma.status == 2 || ma.status == 3 || ma.status == 0 %>
    • <% if ma.status == 1 || ma.status == 2 || ma.status == 3 %> <%= image_tag("/images/trustie_logo1.png", width: "30px", height: "30px", class: "mt3") %> - <% elsif ma.status == 4 %> + <% elsif ma.status == 0 %> <%= link_to image_tag(url_to_avatar(ma.user), :width => "30", :height => "30"), user_path(ma.user), :target => '_blank' %> <% end %> @@ -34,7 +34,7 @@ <%= link_to "“"+ma.name+"”" + "的申请,因名称不合法,已被拒绝,请重新编辑您的基本资料", { :controller=> "my",:action => "account" }, :title => "“#{ma.name}”的申请,因名称不合法,已被拒绝,请重新编辑您的基本资料", :target => '_blank'%>
    • <%= time_tag(ma.created_at).html_safe %>
    • - <% elsif ma.status == 4 %> + <% elsif ma.status == 0 %> <%=link_to User.where("id=?", ma.applied_user_id).first.show_name, user_path(ma.user), :class => "newsBlue homepageNewsPublisher", :target => '_blank' %> "> 申请了单位:
    • From dde89b72faa80aea5d629178e23f9c1259c86c51 Mon Sep 17 00:00:00 2001 From: yuanke <249218296@qq.com> Date: Mon, 1 Aug 2016 15:50:21 +0800 Subject: [PATCH 17/78] =?UTF-8?q?=E5=8A=A0=E5=85=A5=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E4=BA=8C=E7=BB=B4=E7=A0=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/wechats_controller.rb | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/app/controllers/wechats_controller.rb b/app/controllers/wechats_controller.rb index 9afca5c3a..87ede1365 100644 --- a/app/controllers/wechats_controller.rb +++ b/app/controllers/wechats_controller.rb @@ -49,13 +49,7 @@ class WechatsController < ActionController::Base # When no any on :scan responder can match subscribe user scaned scene_id on :event, with: 'scan' do |request| if request[:EventKey].present? - - - - - - - sendBindClass(request, {ticket: request[:Ticket]}) + checkTicket(request, {ticket: request[:Ticket]}) end end From 0ffeec64e3c3a5879fede8a7f86813d5263d734a Mon Sep 17 00:00:00 2001 From: daiao <358551898@qq.com> Date: Mon, 1 Aug 2016 16:10:57 +0800 Subject: [PATCH 18/78] =?UTF-8?q?=E5=8D=95=E4=BD=8D=E5=AE=A1=E6=A0=B8bug?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/admin/applied_schools.html.erb | 2 +- app/views/admin/has_applied_schools.html.erb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/admin/applied_schools.html.erb b/app/views/admin/applied_schools.html.erb index 2f139ca72..d1f0acfa1 100644 --- a/app/views/admin/applied_schools.html.erb +++ b/app/views/admin/applied_schools.html.erb @@ -55,7 +55,7 @@ <%= apply.name %> - + <% user = User.where("id=?", apply.user_id).first %> diff --git a/app/views/admin/has_applied_schools.html.erb b/app/views/admin/has_applied_schools.html.erb index 1b6341fb3..971c8cb0d 100644 --- a/app/views/admin/has_applied_schools.html.erb +++ b/app/views/admin/has_applied_schools.html.erb @@ -60,7 +60,7 @@ <% unless apply.school_id.nil? %> <% school_name = School.where("id=?", apply.school_id).first %> <%= school_name.name %> - + <% end %> From fc38ef6a3fe3692847bf873d5e74860be0220e33 Mon Sep 17 00:00:00 2001 From: guange <8863824@gmail.com> Date: Mon, 1 Aug 2016 19:16:51 +0800 Subject: [PATCH 19/78] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86=E4=B8=80?= =?UTF-8?q?=E4=B8=AA=E6=9F=A5=E7=9C=8B=E6=9C=8D=E5=8A=A1=E5=99=A8=E5=86=85?= =?UTF-8?q?=E7=BD=91ip=E7=9A=84middleware=EF=BC=8C=E5=88=A9=E4=BA=8E?= =?UTF-8?q?=E4=BB=A5=E5=90=8E=E5=88=86=E6=9E=90=E9=97=AE=E9=A2=98=EF=BC=8C?= =?UTF-8?q?headers=E4=B8=BAX-Response-Ip?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/application.rb | 3 +++ db/schema.rb | 30 ++++++++++++++++++++++++------ lib/response_ip.rb | 20 ++++++++++++++++++++ 3 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 lib/response_ip.rb diff --git a/config/application.rb b/config/application.rb index 3885751f7..4b25d4278 100644 --- a/config/application.rb +++ b/config/application.rb @@ -3,6 +3,7 @@ require File.expand_path('../boot', __FILE__) require 'rails/all' require 'sprockets/railtie' require 'elasticsearch/model' + if defined?(Bundler) # If you precompile assets before deploying to production, use this line Bundler.require(*Rails.groups(:assets => %w(development test))) @@ -83,9 +84,11 @@ module RedmineApp end end + config.wechat_srcs = ['app.js','others/factory.js','others/filter.js', 'controllers/*.js', 'directives/*.js', 'others/routes.js'] config.before_initialize do + config.middleware.use ::ResponseIp end config.after_initialize do diff --git a/db/schema.rb b/db/schema.rb index c7d918346..52239eac1 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20160725091759) do +ActiveRecord::Schema.define(:version => 20160729124833) do create_table "activities", :force => true do |t| t.integer "act_id", :null => false @@ -52,9 +52,24 @@ ActiveRecord::Schema.define(:version => 20160725091759) do add_index "api_keys", ["access_token"], :name => "index_api_keys_on_access_token" add_index "api_keys", ["user_id"], :name => "index_api_keys_on_user_id" + create_table "applied_messages", :force => true do |t| + t.integer "user_id" + t.integer "applied_id" + t.string "applied_type" + t.integer "viewed", :default => 0 + t.integer "status", :default => 0 + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "name" + t.integer "applied_user_id" + t.integer "role" + t.integer "project_id" + end + create_table "applied_projects", :force => true do |t| - t.integer "project_id", :null => false - t.integer "user_id", :null => false + t.integer "project_id", :null => false + t.integer "user_id", :null => false + t.integer "role", :default => 0 end create_table "apply_add_schools", :force => true do |t| @@ -577,9 +592,9 @@ ActiveRecord::Schema.define(:version => 20160725091759) do t.integer "excellent_option", :default => 0 t.integer "is_copy", :default => 0 t.integer "visits", :default => 0 - t.integer "syllabus_id" t.string "invite_code" t.string "qrcode" + t.integer "syllabus_id" end add_index "courses", ["invite_code"], :name => "index_courses_on_invite_code", :unique => true @@ -1106,9 +1121,10 @@ ActiveRecord::Schema.define(:version => 20160725091759) do end create_table "member_roles", :force => true do |t| - t.integer "member_id", :null => false - t.integer "role_id", :null => false + t.integer "member_id", :null => false + t.integer "role_id", :null => false t.integer "inherited_from" + t.integer "is_current", :default => 1 end add_index "member_roles", ["member_id"], :name => "index_member_roles_on_member_id" @@ -1539,6 +1555,8 @@ ActiveRecord::Schema.define(:version => 20160725091759) do t.integer "boards_reply_count", :default => 0 t.integer "visits", :default => 0 t.integer "hot", :default => 0 + t.string "invite_code" + t.string "qrcode" end add_index "projects", ["lft"], :name => "index_projects_on_lft" diff --git a/lib/response_ip.rb b/lib/response_ip.rb new file mode 100644 index 000000000..97c93d222 --- /dev/null +++ b/lib/response_ip.rb @@ -0,0 +1,20 @@ +#coding=utf-8 +# +require 'socket' + +class ResponseIp + def initialize(app) + @app = app + end + + def ip + addr = Socket.ip_address_list.detect{|intf| intf.ipv4_private?}.ip_address rescue + addr || '' + end + + def call(env) + status, headers, body = @app.call(env) + headers["X-response-ip"] = ip + [status, headers, body] + end +end From a1d3bbbfa9622d62ae64b1dc06ee64ae5c96fc17 Mon Sep 17 00:00:00 2001 From: guange <8863824@gmail.com> Date: Mon, 1 Aug 2016 19:17:16 +0800 Subject: [PATCH 20/78] =?UTF-8?q?=E8=A7=A3=E5=86=B3ruby2.3=E6=89=A7?= =?UTF-8?q?=E8=A1=8Csql=E5=87=BA=E9=94=99=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/initializers/10-patches.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/config/initializers/10-patches.rb b/config/initializers/10-patches.rb index 79641513e..ff3d8de83 100644 --- a/config/initializers/10-patches.rb +++ b/config/initializers/10-patches.rb @@ -1,5 +1,15 @@ +#coding=utf-8 +# require 'active_record' +## ruby2.3在这个rails版本的activerecord有bug, 直接用respond_to?(:to_proc)作判断 +#而ruby2.3中hash可以返回 to_proc +if RUBY_VERSION > '2.3' && Rails.version < '3.2.22.3' + Hash.class_eval do + remove_method :to_proc + end +end + module ActiveRecord class Base include Redmine::I18n From 0b113bb985203ac0f193191b66e2512a699aecec Mon Sep 17 00:00:00 2001 From: huang Date: Tue, 2 Aug 2016 11:25:19 +0800 Subject: [PATCH 21/78] =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E9=82=80=E8=AF=B7?= =?UTF-8?q?=E7=A0=81=E8=AF=86=E5=88=AB=E5=B0=8F=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/applied_project_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/applied_project_controller.rb b/app/controllers/applied_project_controller.rb index 883fd1c68..eb16549df 100644 --- a/app/controllers/applied_project_controller.rb +++ b/app/controllers/applied_project_controller.rb @@ -53,7 +53,7 @@ class AppliedProjectController < ApplicationController else @project = Project.find(params[:project_id]) end - if !@project || params[:invite_code].to_s != @project.invite_code + if !@project || params[:invite_code].upcase.to_s != @project.invite_code @flag = 1 elsif User.current.member_of?(@project) @flag = 2 From 94b36e227c50c071e51040ba05bef02ed25560ff Mon Sep 17 00:00:00 2001 From: huang Date: Tue, 2 Aug 2016 13:03:33 +0800 Subject: [PATCH 22/78] =?UTF-8?q?=E7=94=B3=E8=AF=B7=E5=8A=A0=E5=85=A5?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E6=B6=88=E6=81=AF=E5=88=B7=E6=96=B0=EF=BC=8C?= =?UTF-8?q?=E5=90=8C=E6=97=B6=E6=9B=B4=E6=96=B0=E5=85=B6=E5=AE=83=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E5=91=98=E7=9A=84=E6=B6=88=E6=81=AF=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/members_controller.rb | 27 +++++++++++++------ .../members/allow_to_join_project.js.erb | 2 +- .../refused_allow_to_join_project.js.erb | 2 +- .../users/_applied_project_content.html.erb | 15 +++++++++++ .../_user_message_applide_action.html.erb | 1 + .../users/_user_message_applied.html.erb | 21 ++------------- 6 files changed, 39 insertions(+), 29 deletions(-) create mode 100644 app/views/users/_applied_project_content.html.erb diff --git a/app/controllers/members_controller.rb b/app/controllers/members_controller.rb index 0a76cfb78..9cac4de3d 100644 --- a/app/controllers/members_controller.rb +++ b/app/controllers/members_controller.rb @@ -75,13 +75,19 @@ class MembersController < ApplicationController project.members << members project.project_infos << project_info project.user_grades << user_grades unless user_grades.first.user_id.nil? - @applied_message.update_attribute(:status, 2) + + # 添加成功后所有管理员收到的消息状态都要更新 + applied_messages = AppliedMessage.where(:applied_id => @applied_message.applied_id, :project_id => @applied_message.project_id, :status => 1, + :applied_type => "AppliedProject") + applied_messages.update_all(:status => 7) + @applied_message = AppliedMessage.find(params[:applied_message_id]) # 添加成功后,申请人收到消息 AppliedMessage.create(:user_id => @applied_message.applied_user_id, :applied_type => "AppliedProject", :applied_id => applied_project.id , - :status => 6, :viewed => true, :applied_user_id => @applied_message.user_id, :role => applied_project.role, :project_id => applied_project.project_id) + :status => 6, :viewed => false, :applied_user_id => @applied_message.user_id, :role => applied_project.role, :project_id => applied_project.project_id) + # 添加成功后,批准人收到消息 - AppliedMessage.create(:user_id => @applied_message.user_id, :applied_type => "AppliedProject", :applied_id => applied_project.id , - :status => 7, :viewed => true, :applied_user_id => @applied_message.applied_user_id, :role => applied_project.role, :project_id => applied_project.project_id) + # AppliedMessage.create(:user_id => @applied_message.user_id, :applied_type => "AppliedProject", :applied_id => applied_project.id , + # :status => 7, :viewed => true, :applied_user_id => @applied_message.applied_user_id, :role => applied_project.role, :project_id => applied_project.project_id) rescue Exception => e puts e end @@ -95,14 +101,19 @@ class MembersController < ApplicationController # status(1:申请的消息;2:已操作过该消息(包括同意或者拒绝,消息状态更新);3:拒绝消息;4:被拒人收到消息;5:拒绝者收到消息;6:同意后申请人收到消息;7:同意后批准人收到消息) def refused_allow_to_join_project @applied_message = AppliedMessage.find(params[:applied_message_id]) - @applied_message.update_attribute(:status, 3) + # @applied_message.update_attribute(:status, 3) applied_project = @applied_message.applied # 发送消息给被拒者,user_id对应的收到信息的用户 AppliedMessage.create(:user_id => @applied_message.applied_user_id, :applied_type => "AppliedProject", :applied_id => applied_project.id ,:status => 4, :viewed => true, :applied_user_id => @applied_message.user_id, :role => applied_project.role, :project_id => applied_project.project_id) - # 发送消息给拒绝者 - AppliedMessage.create(:user_id => @applied_message.user_id, :applied_type => "AppliedProject", :applied_id => applied_project.id ,:status => 5, - :viewed => true, :applied_user_id => @applied_message.applied_user_id, :role => applied_project.role, :project_id => applied_project.project_id) + + # 拒绝功后所有管理员收到的消息状态都要更新 + applied_messages = AppliedMessage.where(:applied_id => @applied_message.applied_id, :project_id => @applied_message.project_id, :status => 1, + :applied_type => "AppliedProject") + applied_messages.update_all(:status => 5) + @applied_message = AppliedMessage.find(params[:applied_message_id]) + # AppliedMessage.create(:user_id => @applied_message.user_id, :applied_type => "AppliedProject", :applied_id => applied_project.id ,:status => 5, + # :viewed => true, :applied_user_id => @applied_message.applied_user_id, :role => applied_project.role, :project_id => applied_project.project_id) applied_project.delete end diff --git a/app/views/members/allow_to_join_project.js.erb b/app/views/members/allow_to_join_project.js.erb index cbd37e188..222511942 100644 --- a/app/views/members/allow_to_join_project.js.erb +++ b/app/views/members/allow_to_join_project.js.erb @@ -1,5 +1,5 @@ <% if @flash_message %> alert("<%= @flash_message %>"); <% else%> - $("#applied_project_<%= @applied_message.id %>").html('<%= render :partial => "users/user_message_applide_action", :locals =>{:ma => @applied_message} %>'); + $("#applied_project_<%= @applied_message.id %>").html('<%= escape_javascript(render :partial => 'users/applied_project_content', :locals => {:ma => @applied_message}) %>'); <% end%> diff --git a/app/views/members/refused_allow_to_join_project.js.erb b/app/views/members/refused_allow_to_join_project.js.erb index 109ed3a62..57211334f 100644 --- a/app/views/members/refused_allow_to_join_project.js.erb +++ b/app/views/members/refused_allow_to_join_project.js.erb @@ -1 +1 @@ -$("#applied_project_<%= @applied_message.id %>").html('<%= render :partial => "users/user_message_applide_action", :locals =>{:ma => @applied_message} %>'); \ No newline at end of file +$("#applied_project_<%= @applied_message.id %>").html('<%= escape_javascript(render :partial => 'users/applied_project_content', :locals => {:ma => @applied_message}) %>'); \ No newline at end of file diff --git a/app/views/users/_applied_project_content.html.erb b/app/views/users/_applied_project_content.html.erb new file mode 100644 index 000000000..2d9c7b109 --- /dev/null +++ b/app/views/users/_applied_project_content.html.erb @@ -0,0 +1,15 @@ +
    • + <%=link_to image_tag(url_to_avatar(applied_project_users(ma)), :width => "30", :height => "30"), user_path(applied_project_users(ma)), :target => '_blank' %> +
    • +
    • + <%= render :partial => "users/user_message_applide_users", :locals =>{:ma => ma} %> +
    • +
    • + 以“<%= applied_project_message_type(ma.role) %>”身份加入<% project = Project.find(ma.project_id) %> + <%= link_to project.name, project_path(ma.project_id), :class => "link-blue", :target => '_blank', :title => "#{project.name}" %> + +
    • +
    • + <%= render :partial => "users/user_message_applide_action", :locals =>{:ma => ma} %> +
    • +
    • <%= time_tag(ma.created_at).html_safe %>
    • \ No newline at end of file diff --git a/app/views/users/_user_message_applide_action.html.erb b/app/views/users/_user_message_applide_action.html.erb index 48e479b22..a8b5598fa 100644 --- a/app/views/users/_user_message_applide_action.html.erb +++ b/app/views/users/_user_message_applide_action.html.erb @@ -1,3 +1,4 @@ +<% ma = ma.nil? ? @applied_message : ma %> <% if allow_to_show(ma) %> <%= link_to "同意", allow_to_join_project_project_memberships_path(:project_id => ma.project_id, :applied_message_id => ma.id), :remote => true, :method => :post, :class => "link-blue"%> | <%= link_to "拒绝", refused_allow_to_join_project_project_memberships_path(:project_id => ma.project_id, :applied_message_id => ma.id), :remote => true, :method => :get, :class => "link-blue" %> diff --git a/app/views/users/_user_message_applied.html.erb b/app/views/users/_user_message_applied.html.erb index dbe01c4b4..6d853f01c 100644 --- a/app/views/users/_user_message_applied.html.erb +++ b/app/views/users/_user_message_applied.html.erb @@ -47,25 +47,8 @@
    <% end %> <% elsif ma && ma.applied_type == "AppliedProject" %> -
      -
    • - <%=link_to image_tag(url_to_avatar(applied_project_users(ma)), :width => "30", :height => "30"), user_path(applied_project_users(ma)), :target => '_blank' %> -
    • -
    • - <%= render :partial => "users/user_message_applide_users", :locals =>{:ma => ma} %> -
    • -
    • - 以“<%= applied_project_message_type(ma.role) %>”身份加入 - <% project = Project.find(ma.project_id) %> - <%= link_to project.name, project_path(ma.project_id), :class => "link-blue", :target => '_blank', :title => "#{project.name}" %> - -
    • -
    • - - <%= render :partial => "users/user_message_applide_action", :locals =>{:ma => ma} %> - -
    • -
    • <%= time_tag(ma.created_at).html_safe %>
    • +
        + <%= render :partial => "users/applied_project_content", :locals =>{:ma => ma} %>
      <% end %> <% end %> \ No newline at end of file From 5e4a659cba976b7716b2df87242deb38b3f43b27 Mon Sep 17 00:00:00 2001 From: huang Date: Tue, 2 Aug 2016 13:04:40 +0800 Subject: [PATCH 23/78] gemfile --- Gemfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index 1c1edfd35..80c0e1c2a 100644 --- a/Gemfile +++ b/Gemfile @@ -50,10 +50,10 @@ gem 'elasticsearch-model' gem 'elasticsearch-rails' #rails 3.2.22.2 bug -gem "test-unit", "~>3.0" + gem "test-unit", "~>3.0" ### profile -gem 'oneapm_rpm' + gem 'oneapm_rpm' group :development do gem 'grape-swagger' From 7658844a28061da611ef4f2ae3e29f21c5087a5e Mon Sep 17 00:00:00 2001 From: huang Date: Tue, 2 Aug 2016 14:53:33 +0800 Subject: [PATCH 24/78] =?UTF-8?q?=E9=BC=A0=E6=A0=87=E7=BB=8F=E8=BF=87?= =?UTF-8?q?=E5=BC=B9=E6=A1=86=E6=B6=88=E6=81=AF=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/members_controller.rb | 8 +++--- app/helpers/users_helper.rb | 25 +++++++++++++++++++ .../layouts/_show_messages_list.html.erb | 7 ++++++ 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/app/controllers/members_controller.rb b/app/controllers/members_controller.rb index 9cac4de3d..f14416442 100644 --- a/app/controllers/members_controller.rb +++ b/app/controllers/members_controller.rb @@ -79,7 +79,7 @@ class MembersController < ApplicationController # 添加成功后所有管理员收到的消息状态都要更新 applied_messages = AppliedMessage.where(:applied_id => @applied_message.applied_id, :project_id => @applied_message.project_id, :status => 1, :applied_type => "AppliedProject") - applied_messages.update_all(:status => 7) + applied_messages.update_all(:status => 7, :viewed => true) @applied_message = AppliedMessage.find(params[:applied_message_id]) # 添加成功后,申请人收到消息 AppliedMessage.create(:user_id => @applied_message.applied_user_id, :applied_type => "AppliedProject", :applied_id => applied_project.id , @@ -105,12 +105,12 @@ class MembersController < ApplicationController applied_project = @applied_message.applied # 发送消息给被拒者,user_id对应的收到信息的用户 AppliedMessage.create(:user_id => @applied_message.applied_user_id, :applied_type => "AppliedProject", :applied_id => applied_project.id ,:status => 4, - :viewed => true, :applied_user_id => @applied_message.user_id, :role => applied_project.role, :project_id => applied_project.project_id) + :viewed => false, :applied_user_id => @applied_message.user_id, :role => applied_project.role, :project_id => applied_project.project_id) # 拒绝功后所有管理员收到的消息状态都要更新 applied_messages = AppliedMessage.where(:applied_id => @applied_message.applied_id, :project_id => @applied_message.project_id, :status => 1, - :applied_type => "AppliedProject") - applied_messages.update_all(:status => 5) + :applied_type => "AppliedProject") + applied_messages.update_all(:status => 5, :viewed => true) @applied_message = AppliedMessage.find(params[:applied_message_id]) # AppliedMessage.create(:user_id => @applied_message.user_id, :applied_type => "AppliedProject", :applied_id => applied_project.id ,:status => 5, # :viewed => true, :applied_user_id => @applied_message.applied_user_id, :role => applied_project.role, :project_id => applied_project.project_id) diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb index 91743289a..1bb76b6fd 100644 --- a/app/helpers/users_helper.rb +++ b/app/helpers/users_helper.rb @@ -80,6 +80,19 @@ module UsersHelper # end end + def applied_project_status applied_message + case applied_message.status + when 4 + "被拒绝" + when 5 + "您已拒绝" + when 6 + "已通过" + when 7 + "您已同意" + end + end + # 项目申请消息通过状态判断tip描述 def applied_project_tip applied_message case applied_message.status @@ -92,6 +105,18 @@ module UsersHelper end end + def applied_project_tip_header applied_message + case applied_message.status + when 4 + "婉拒您" + when 5,3,2,1,7 + "申请:" + when 6 + "同意您" + end + end + + def get_resource_origin attach type = attach.container_type content = attach.container diff --git a/app/views/layouts/_show_messages_list.html.erb b/app/views/layouts/_show_messages_list.html.erb index 0829b9c42..a30d86d07 100644 --- a/app/views/layouts/_show_messages_list.html.erb +++ b/app/views/layouts/_show_messages_list.html.erb @@ -88,6 +88,13 @@ <% elsif ma.course_message_type == "Exercise" && ma.status == 3 %>
    • <%=ma.course_message.user.show_name %>老师 发布的测验:<%=ma.course_message.exercise_name %> 截止时间快到了
    • <% end %> + <% elsif ma.class == AppliedMessage %> + <% if ma.applied_type == "AppliedProject" %> +
    • <%=link_to "#{applied_project_users(ma)}".html_safe, user_path(applied_project_users(ma)), :target => '_blank' %> + <%= applied_project_tip_header(ma) %>以“<%= applied_project_message_type(ma.role) %>”身份加入<% project = Project.find(ma.project_id) %> + <%= link_to project.name, project_path(ma.project_id), :class => "link-blue", :target => '_blank', :title => "#{project.name}" %> + + <% end %> <% elsif ma.class == ForgeMessage %> <% if ma.forge_message_type == "AppliedProject" %>
    • " target="_blank" title="<%=ma.forge_message.user.show_name %> 申请加入项目:<%= ma.project.name%>"><%=ma.forge_message.user.show_name %> 申请加入项目:<%= ma.project.name%>
    • From 614e877e6e10a1c6b820c0153bd7eb9b872c4101 Mon Sep 17 00:00:00 2001 From: yuanke <249218296@qq.com> Date: Tue, 2 Aug 2016 15:50:15 +0800 Subject: [PATCH 25/78] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E5=92=8C=E7=8F=AD=E7=BA=A7=E5=8A=A0=E5=85=A5=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/mobile/apis/courses.rb | 103 +++++++++-- app/api/mobile/apis/projects.rb | 15 +- app/api/mobile/entities/project_member.rb | 4 +- app/services/courses_service.rb | 164 ++++++++++++++++-- app/services/projects_service.rb | 25 +-- public/assets/wechat/class.html | 10 +- public/assets/wechat/edit_class_member.html | 8 +- public/assets/wechat/join_class.html | 19 ++ public/assets/wechat/join_project.html | 20 +++ public/assets/wechat/review_class_member.html | 18 ++ .../assets/wechat/review_project_member.html | 20 +++ .../javascripts/wechat/controllers/class.js | 18 ++ .../wechat/controllers/class_list.js | 45 ++--- .../wechat/controllers/edit_class_member.js | 56 +++++- .../wechat/controllers/edit_project_member.js | 1 + .../wechat/controllers/join_class.js | 72 ++++++++ .../wechat/controllers/join_project.js | 52 ++++++ .../wechat/controllers/project_list.js | 43 ++--- .../wechat/controllers/review_class_member.js | 68 ++++++++ .../controllers/review_project_member.js | 109 ++++++++++++ public/javascripts/wechat/others/routes.js | 4 + 21 files changed, 779 insertions(+), 95 deletions(-) create mode 100644 public/assets/wechat/join_class.html create mode 100644 public/assets/wechat/join_project.html create mode 100644 public/assets/wechat/review_class_member.html create mode 100644 public/assets/wechat/review_project_member.html create mode 100644 public/javascripts/wechat/controllers/join_class.js create mode 100644 public/javascripts/wechat/controllers/join_project.js create mode 100644 public/javascripts/wechat/controllers/review_class_member.js create mode 100644 public/javascripts/wechat/controllers/review_project_member.js diff --git a/app/api/mobile/apis/courses.rb b/app/api/mobile/apis/courses.rb index eec6e8ead..402702659 100644 --- a/app/api/mobile/apis/courses.rb +++ b/app/api/mobile/apis/courses.rb @@ -100,15 +100,34 @@ module Mobile params do requires :token, type: String requires :invite_code, type: String, desc: '邀请码' + requires :teacher_flag, type: Boolean + requires :assistant_flag, type: Boolean + requires :student_flag, type: Boolean end - post "join" do + post "join_class" do authenticate! - cs = CoursesService.new - status = cs.join_course({role: "10", openid: params[:openid], invite_code: params[:invite_code]}, current_user) - { - status: status[:state], - message:CoursesService::JoinCourseError.message(status[:state]) - } + + roles_ids = [] + if params[:teacher_flag] + roles_ids << "9" + elsif params[:assistant_flag] + roles_ids << "7" + end + + if params[:student_flag] + roles_ids << "10" + end + + if roles_ids.length <= 0 + {status:-1,message:"请至少选择一个角色"} + else + cs = CoursesService.new + status = cs.join_course_roles({role: roles_ids, openid: params[:openid], invite_code: params[:invite_code]}, current_user) + { + status: status[:state], + message:CoursesService::JoinCourseError.message(status[:state]) + } + end end @@ -166,7 +185,52 @@ module Mobile present :status, 0 end - desc "设置教辅" + desc "课程未审核列表" + params do + requires :token, type: String + requires :course_id, type: Integer, desc: "课程id" + end + get 'reviewers' do + authenticate! + cs = CoursesService.new + reviewers = cs.reviewers_list(params[:course_id]) + present :data, reviewers, with: Mobile::Entities::User + present :status, 0 + end + + desc "课程单个未审核用户信息" + params do + requires :token, type: String + requires :course_id, type: Integer, desc: "课程id" + requires :user_id, type: Integer, desc: "用户id" + end + post 'review_member_info' do + authenticate! + + cs = CoursesService.new + reviewer = cs.get_reviewer_info(params) + present :data, reviewer, with: Mobile::Entities::User + present :status, 0 + end + + desc "处理教师或助教的身份申请" + params do + requires :token, type: String + requires :course_id, type: Integer, desc: "课程id" + requires :user_id, type: Integer, desc: "用户id" + requires :type, type: Integer, desc: "同意或拒绝" + end + post 'deal_join_apply' do + authenticate! + + cs = CoursesService.new + result = cs.deal_join_apply(params,current_user) + + present :status, result[:status] + present :message, result[:message] + end + + desc "设置助教" params do requires :token,type:String requires :user_id,type:Integer,desc: '用户id' @@ -178,7 +242,7 @@ module Mobile present :status, 0 end - desc "删除教辅" + desc "删除助教" params do requires :token,type:String requires :user_id,type:Integer,desc: '用户id' @@ -448,20 +512,35 @@ module Mobile requires :id, type: Integer requires :token, type: String requires :user_id, type: Integer - requires :role_id, type: Integer + requires :teacher_flag, type: Boolean + requires :assistant_flag, type: Boolean + requires :student_flag, type: Boolean end post 'edit_member_role' do authenticate! + roles_id = [] + + if params[:teacher_flag] + roles_id << 9 + elsif params[:assistant_flag] + roles_id << 7 + end + + if params[:student_flag] + roles_id << 10 + end + + c = Course.find("#{params[:id]}") #7教辅 9教师 10学生 - if c.tea_id == params[:user_id] || c.tea_id != current_user.id || !(params[:role_id] == 7 || params[:role_id] == 9 || params[:role_id] == 10) + if c.tea_id == params[:user_id] || c.tea_id != current_user.id || roles_id.length <= 0 present :status, -1 else cs = CoursesService.new - status = cs.modify_user_course_role params + status = cs.modify_user_course_role params,roles_id present :status, status end end diff --git a/app/api/mobile/apis/projects.rb b/app/api/mobile/apis/projects.rb index bdb824694..f3242845f 100644 --- a/app/api/mobile/apis/projects.rb +++ b/app/api/mobile/apis/projects.rb @@ -163,14 +163,21 @@ module Mobile params do requires :token, type: String requires :invite_code, type: String, desc: '邀请码' + requires :role_id, type: Integer, desc: '身份' end - post "join" do + post "join_project" do authenticate! - ps = ProjectsService.new - status = ps.join_project({role: "5", openid: params[:openid], invite_code: params[:invite_code]}, current_user) + role_id = params[:role_id] - {status:status, message:ProjectsService::JoinProjectError.message(status)} + if role_id != 3 && role_id != 4 && role_id != 5 + {status:-1,message:"请至少选择一个角色"} + else + ps = ProjectsService.new + status = ps.join_project({role: role_id, openid: params[:openid], invite_code: params[:invite_code]}, current_user) + + {status:status, message:ProjectsService::JoinProjectError.message(status)} + end # {status:-1, message: '该功能将在近日开放,敬请期待!' } end diff --git a/app/api/mobile/entities/project_member.rb b/app/api/mobile/entities/project_member.rb index 58edf7ea7..decd7dac3 100644 --- a/app/api/mobile/entities/project_member.rb +++ b/app/api/mobile/entities/project_member.rb @@ -14,11 +14,11 @@ module Mobile else case f when :roles_id - u.roles[0].id + # u.roles[0].id + u.roles.map {|r| r.id} end end end - end end diff --git a/app/services/courses_service.rb b/app/services/courses_service.rb index ce3157d5f..c8401f051 100644 --- a/app/services/courses_service.rb +++ b/app/services/courses_service.rb @@ -111,6 +111,129 @@ class CoursesService users end + def reviewers_list course_id + reviewers = [] + c = Course.find(course_id) + + if c + messages = CourseMessage.where("course_id=? and course_message_type = 'JoinCourseRequest' and status = 0 ",course_id) + + messages.each do |m| + user = User.find(m.course_message_id) + + if user + img_url = url_to_avatar(user) + gender = user.user_extensions.gender.nil? ? 0 : user.user_extensions.gender + work_unit = get_user_work_unit user + location = get_user_location user + roles_ids = m.content.split(",") + reviewers << {:id => user.id, :img_url => img_url, :nickname => user.login, :gender => gender, + :work_unit => work_unit, :mail => user.mail, :location => location, + role_name: "", + name: user.show_name, + roles_id: roles_ids.include?("7") ? 7 : 9, + :brief_introduction => user.user_extensions.brief_introduction,:realname=>user.realname} + end + end + + end + + reviewers + end + + def get_reviewer_info params + info = nil + c = Course.find(params[:course_id]) + if c + messages = CourseMessage.where("course_id=? and course_message_id = ? and course_message_type = 'JoinCourseRequest' and status = 0 ",params[:course_id],params[:user_id]).first + + if messages + user = User.find(params[:user_id]) + if user + img_url = url_to_avatar(user) + gender = user.user_extensions.gender.nil? ? 0 : user.user_extensions.gender + work_unit = get_user_work_unit user + location = get_user_location user + roles_ids = messages.content.split(",") + info = {:id => user.id, :img_url => img_url, :nickname => user.login, :gender => gender, + :work_unit => work_unit, :mail => user.mail, :location => location, + role_name: "", + name: user.show_name, + roles_id: roles_ids.include?("7") ? 7 : 9, + :brief_introduction => user.user_extensions.brief_introduction,:realname=>user.realname} + end + end + end + + info + end + + def deal_join_apply params,current_user + status = -1 + message = "" + + c = Course.find(params[:course_id]) + + if c + messages = CourseMessage.where("course_id=? and course_message_id = ? and course_message_type = 'JoinCourseRequest' and status = 0 ",params[:course_id],params[:user_id]).first + if messages + apply_user = User.find(params[:user_id]) + ids = messages.content.split(",") # content保存的是申请的职位角色 + integer_ids = [] + ids.each do |role_id| + integer_ids << role_id.to_i + end + + if params[:type] == 0 + + if apply_user.member_of_course?(c) + #将角色改为老师或者教辅 + member = c.members.where(:user_id=>apply_user.id).all[0] + member.role_ids = integer_ids + #删除为学生的记录 + unless member.role_ids.include?(10) + joined = StudentsForCourse.where('student_id = ? and course_id = ?', member.user_id,c.id) + joined.each do |join| + join.delete + end + end + + member.course_group_id = 0 + member.save + CourseMessage.create(:user_id => apply_user.id, :course_id => c.id, :viewed => false,:content=> messages.content,:course_message_id=>current_user.id,:course_message_type=>'CourseRequestDealResult',:status=>1) + messages.update_attributes(:status=>1,:viewed=>1) + else + members = [] + members << Member.new(:role_ids => integer_ids, :user_id => apply_user.id) + c.members << members + CourseMessage.create(:user_id => apply_user.id, :course_id => c.id, :viewed => false,:content=> messages.content,:course_message_id=>current_user.id,:course_message_type=>'CourseRequestDealResult',:status=>1) + messages.update_attributes(:status=>1,:viewed=>1) + end + if integer_ids.include?(9) + message = "您已同意教师"+apply_user.show_name+",加入班级" + else + message = "您已同意助教"+apply_user.show_name+",加入班级" + end + else + CourseMessage.create(:user_id => apply_user.id, :course_id => c.id, :viewed => false,:content=> messages.content,:course_message_id=>current_user.id,:course_message_type=>'CourseRequestDealResult',:status=>2) + message.update_attributes(:status=>2,:viewed=>1) + if integer_ids.include?(9) + message = "您已拒绝教师"+apply_user.show_name+",加入班级" + else + message = "您已拒绝助教"+apply_user.show_name+",加入班级" + end + end + status = 0 + else + message = "该申请不存在或已被处理" + end + else + message = "该班级不存在或已被删除" + end + + {:status => status,:message => message} + end + #获取用户的工作单位 def get_user_work_unit user work_unit = "" @@ -329,15 +452,17 @@ class CoursesService 0, '加入成功', 1, '密码错误', 2, '班级已过期 请联系班级管理员重启班级。', - 3, '您已经加入了班级', + 3, '您已经是该班级的成员了', 4, '您的邀请码不正确', 5, '您还未登录', - 6, '申请成功,请等待审核完毕', + 6, '您的申请已提交,请等待管理员审批', 7, '您已经发送过申请了,请耐心等待', 8, '您已经是该班级的教师了', 9, '您已经是该班级的教辅了', 10, '您已经是该班级的管理员了', 11, '该班级不存在或已被删除啦', + 12, '您已经发送过申请了,请耐心等待', + 13, '您的申请已提交,请等待管理员审批', '未知错误,请稍后再试' ] end @@ -460,15 +585,31 @@ class CoursesService is_stu = true end #如果已经发送过消息了,那么就要给个提示 - if CourseMessage.where("course_message_type = 'JoinCourseRequest' and user_id = #{course.tea_id} and content = '#{role_str}' and course_message_id = #{User.current.id} and course_id = #{course.id} and status = 0").count != 0 + if CourseMessage.where("course_message_type = 'JoinCourseRequest' and user_id = #{course.tea_id} and content = '#{role_str}' and course_message_id = #{current_user.id} and course_id = #{course.id} and status = 0").count != 0 if is_stu @state = 12 else @state = 7 end else - Mailer.run.join_course_request(course, User.current, params[:role]) - CourseMessage.create(:user_id => course.tea_id, :course_id => course.id, :viewed => false,:content=> role_str,:course_message_id=>User.current.id,:course_message_type=>'JoinCourseRequest',:status=>0) + Mailer.run.join_course_request(course, current_user, params[:role]) + CourseMessage.create(:user_id => course.tea_id, :course_id => course.id, :viewed => false,:content=> role_str,:course_message_id=>current_user.id,:course_message_type=>'JoinCourseRequest',:status=>0) + + #----------------微信通知---------------------- + + if role_ids.include?("7") || role_ids.include?("9") + tea_user = User.find(course.tea_id) + count = ShieldWechatMessage.where("container_type='User' and container_id=#{tea_user.id} and shield_type='Course' and shield_id=#{course.id}").count + if count == 0 + + rolename = role_ids.include?("7") ? "助教" : "教师" + content = current_user.show_name + "申请以"+rolename+"身份加入班级,等待您的审批。" + ws = WechatService.new + ws.class_notice tea_user.id, "course_join_review", course.id, "班级成员审批通知", course.name, tea_user.show_name, format_time(Time.now), content, "点击查看申请详情" + end + end + #-------------------------------------------- + if is_stu @state = 13 else @@ -1054,20 +1195,21 @@ class CoursesService # end #修改班级成员角色 - def modify_user_course_role params + def modify_user_course_role params,roles_id status = -1 c = Course.find("#{params[:id]}") - member = c.member_principals.includes(:roles, :principal).where("user_id=?",params[:user_id]).first + # member = c.member_principals.includes(:roles, :principal).where("user_id=?",params[:user_id]).first + member = c.members.where("user_id=?",params[:user_id]).first if member - role = Role.find(params[:role_id]) + member.role_ids = roles_id - member.member_roles[0].role_id = params[:role_id] + role = Role.find(roles_id[0]) # 这里的判断只能通过角色名,可以弄成常量 - if params[:role_id] == 10 + if roles_id && roles_id.include?(10) StudentsForCourse.create(:student_id => params[:user_id], :course_id =>params[:id]) else joined = StudentsForCourse.where('student_id = ? and course_id = ?', params[:user_id],params[:id]) @@ -1090,7 +1232,7 @@ class CoursesService Role.givable.all[3..5] - if member.member_roles[0].save + if member.save status = 0 end end diff --git a/app/services/projects_service.rb b/app/services/projects_service.rb index 2d5e3bf08..f519059d2 100644 --- a/app/services/projects_service.rb +++ b/app/services/projects_service.rb @@ -125,20 +125,25 @@ class ProjectsService status = member.member_roles[0].role_id else if params[:invite_code].present? - members = [] - user_grades = [] - project_info = [] - user_grades << UserGrade.new(:user_id => current_user.id, :project_id => project.id) - project.user_grades << user_grades unless user_grades.first.user_id.nil? + if params[:role_id] == 5 + members = [] + user_grades = [] + project_info = [] - members << Member.new(:role_ids => ["5"], :user_id => current_user.id) - project.members << members + user_grades << UserGrade.new(:user_id => current_user.id, :project_id => project.id) + project.user_grades << user_grades unless user_grades.first.user_id.nil? - project_info << ProjectInfo.new(:user_id => current_user.id, :project_id => project.id) - project.project_infos << project_info + members << Member.new(:role_ids => ["5"], :user_id => current_user.id) + project.members << members - status = 0 + project_info << ProjectInfo.new(:user_id => current_user.id, :project_id => project.id) + project.project_infos << project_info + + status = 0 + else + + end else status = 4 end diff --git a/public/assets/wechat/class.html b/public/assets/wechat/class.html index 5b9b71b0d..4fadcbd9d 100644 --- a/public/assets/wechat/class.html +++ b/public/assets/wechat/class.html @@ -34,9 +34,17 @@ {{teacher.name}} 管理员 - 教辅 + 助教
      + +
      + {{reviewer.name}} + 待审批 +
      +
      + +
      我的同学
      {{student.name}} diff --git a/public/assets/wechat/edit_class_member.html b/public/assets/wechat/edit_class_member.html index 2a15af150..c20ed5acb 100644 --- a/public/assets/wechat/edit_class_member.html +++ b/public/assets/wechat/edit_class_member.html @@ -5,9 +5,9 @@
      {{current_edit_member.user.realname == "" ? current_edit_member.user.name : current_edit_member.user.realname}}
      角色
        -
      • -
      • -
      • +
      • +
      • +
      取消 @@ -15,7 +15,5 @@
      - - diff --git a/public/assets/wechat/join_class.html b/public/assets/wechat/join_class.html new file mode 100644 index 000000000..18848190e --- /dev/null +++ b/public/assets/wechat/join_class.html @@ -0,0 +1,19 @@ +
      +
      +
      +
      欢迎加入班级
      +
      班级邀请码
      +
      角色
      +
        +
      • +
      • +
      • +
      +
      + 取消 + 确定 +
      +
      + + +
      diff --git a/public/assets/wechat/join_project.html b/public/assets/wechat/join_project.html new file mode 100644 index 000000000..3ab29bf70 --- /dev/null +++ b/public/assets/wechat/join_project.html @@ -0,0 +1,20 @@ +
      +
      +
      +
      欢迎加入项目
      +
      项目邀请码
      +
      角色
      +
        +
      • +
      • +
      • +
      +
      + 取消 + 确定 +
      +
      + + + +
      diff --git a/public/assets/wechat/review_class_member.html b/public/assets/wechat/review_class_member.html new file mode 100644 index 000000000..81d2e03d6 --- /dev/null +++ b/public/assets/wechat/review_class_member.html @@ -0,0 +1,18 @@ +
      +
      +
      +
      {{current_course.name}}
      +
      {{current_review_member.realname == "" ? current_review_member.name : current_review_member.realname}}
      +
      角色
      +
        +
      • +
      • +
      +
      + 拒绝 + 同意 +
      +
      + + +
      diff --git a/public/assets/wechat/review_project_member.html b/public/assets/wechat/review_project_member.html new file mode 100644 index 000000000..1e556780b --- /dev/null +++ b/public/assets/wechat/review_project_member.html @@ -0,0 +1,20 @@ +
      +
      +
      +
      角色变更
      +
      项目邀请码
      +
      角色
      +
        +
      • +
      • +
      • +
      +
      + 取消 + 确定 +
      +
      + + + +
      diff --git a/public/javascripts/wechat/controllers/class.js b/public/javascripts/wechat/controllers/class.js index 490ecc033..04807b2dd 100644 --- a/public/javascripts/wechat/controllers/class.js +++ b/public/javascripts/wechat/controllers/class.js @@ -15,6 +15,17 @@ app.controller('ClassController', ['$scope', 'config','$http', 'auth','$location ) } + if(vm.course.is_creator){ + if(vm.reviewers.length<=0){ + $http.get(config.apiUrl + 'courses/reviewers?token='+auth.token()+'&course_id='+courseid).then( + function(response) { + console.log(response.data); + vm.reviewers = response.data.data; + } + ) + } + } + if(vm.students.length<=0){ $http.get(config.apiUrl + 'courses/students?token='+auth.token()+'&course_id='+courseid).then( function(response) { @@ -100,6 +111,7 @@ app.controller('ClassController', ['$scope', 'config','$http', 'auth','$location vm.course = {}; vm.students = []; vm.teachers = []; + vm.reviewers = []; //待审批 vm.resources = []; vm.homeworks = []; vm.exercises = []; @@ -157,6 +169,12 @@ app.controller('ClassController', ['$scope', 'config','$http', 'auth','$location $location.path("/edit_class_member").search({id: courseid,user_id: user.id}); }; + vm.review = function(user){ + rms.save('current_review_member', user); + rms.save('current_course', vm.course); + + $location.path("/review_class_member").search({id: courseid,user_id: user.id}); + } diff --git a/public/javascripts/wechat/controllers/class_list.js b/public/javascripts/wechat/controllers/class_list.js index 488d1913c..d27383a3b 100644 --- a/public/javascripts/wechat/controllers/class_list.js +++ b/public/javascripts/wechat/controllers/class_list.js @@ -51,27 +51,30 @@ app.controller('ClassListController', ['$scope', 'config', 'auth', '$http', '$lo } vm.joinClass = function () { - vm.alertService_3.showMessage('提示', '请输入5位班级邀请码(不区分大小写)', function(){ - if (vm.alertService_3.invite && vm.alertService_3.invite.length == 5) { - $http.post(config.apiUrl + "courses/join", { - token: auth.token(), - invite_code: vm.alertService_3.invite - }).then(function (response) { - console.log(response.data); - if (response.data.status != 0) { - vm.alertService_1.showMessage('提示', response.data.message); - } else { - vm.alertService_1.showMessage('提示', '加入课程成功'); - vm.alertService_3.invite = ""; - loadClassList(); - } - }); - } else { - if(vm.alertService_3.invite){ - vm.alertService_1.showMessage('提示', '邀请码格式不正确'); - } - } - }); +// vm.alertService_3.showMessage('提示', '请输入5位班级邀请码(不区分大小写)', function(){ +// if (vm.alertService_3.invite && vm.alertService_3.invite.length == 5) { +// $http.post(config.apiUrl + "courses/join", { +// token: auth.token(), +// invite_code: vm.alertService_3.invite +// }).then(function (response) { +// console.log(response.data); +// if (response.data.status != 0) { +// vm.alertService_1.showMessage('提示', response.data.message); +// } else { +// vm.alertService_1.showMessage('提示', '加入课程成功'); +// vm.alertService_3.invite = ""; +// loadClassList(); +// } +// }); +// } else { +// if(vm.alertService_3.invite){ +// vm.alertService_1.showMessage('提示', '邀请码格式不正确'); +// } +// } +// }); + + $location.path("/join_class"); + }; vm.onSetting = function (syllabus) { diff --git a/public/javascripts/wechat/controllers/edit_class_member.js b/public/javascripts/wechat/controllers/edit_class_member.js index 2a9987290..b3c28ea0b 100644 --- a/public/javascripts/wechat/controllers/edit_class_member.js +++ b/public/javascripts/wechat/controllers/edit_class_member.js @@ -10,6 +10,16 @@ app.controller('EditClassMemberController', ['$scope', '$http', 'auth', 'config' var course_id = $routeParams.id; var user_id = $routeParams.user_id; + + vm.teacher = false; //教师 + vm.assistant = false; //教辅 + vm.student = false; //学生. + + vm.tmpteacher = false; //教师 + vm.tmpassistant = false; //教辅 + vm.tmpstudent = false; //学生 + + if(!vm.current_edit_member){ $http.post(config.apiUrl+'courses/get_member_info', { token: auth.token(), @@ -19,16 +29,30 @@ app.controller('EditClassMemberController', ['$scope', '$http', 'auth', 'config' if(response.data.status!=0){ vm.alertService.showMessage('提示', response.data.message); } else { + console.log(response); course_id = response.data.course_id; user_id = response.data.user_id; vm.current_edit_member = response.data.member_info; vm.current_roles_id = vm.current_edit_member.roles_id; + + for(var i in vm.current_roles_id){ + if(vm.current_roles_id[i] == 9){ + vm.teacher = true; + vm.tmpteacher = true; + } + else if(vm.current_roles_id[i] == 7){ + vm.assistant = true; + vm.tmpassistant = true; + } + else if(vm.current_roles_id[i] == 10){ + vm.student = true; + vm.tmpstudent = true; + } + } } }); } - console.log(vm.current_edit_member); - vm.cancel = function(){ // vm.alertService.showMessage('提示', '您确定不对角色进行变更吗?', function(){ // window.history.back(); @@ -37,33 +61,49 @@ app.controller('EditClassMemberController', ['$scope', '$http', 'auth', 'config' }; vm.edit_member_role = function(){ - if(vm.current_roles_id == vm.current_edit_member.roles_id){ + if((vm.teacher == vm.tmpteacher)&& (vm.assistant == vm.tmpassistant)&&(vm.student == vm.tmpstudent)){ vm.alertService.showMessage('提示', "该用户当前已是该角色"); return; } + if((vm.teacher == false)&& (vm.assistant == false)&&(vm.student == false)){ + vm.alertService.showMessage('提示', "请至少选择一种角色"); + return; + } + $http.post(config.apiUrl+'courses/edit_member_role', { token: auth.token(), id: course_id, user_id:vm.current_edit_member.user.id, - role_id:vm.current_edit_member.roles_id + teacher_flag:vm.teacher, + assistant_flag:vm.assistant, + student_flag:vm.student }).then(function(response){ if(response.data.status!=0){ vm.alertService.showMessage('提示', response.data.message); } else { vm.alertService.showMessage('提示', '修改角色成功', function(){ // window.history.back(); - $location.path("/class").search({id: course_id,tag:1}); }); } }); - - }; vm.selectRole = function(role_id){ - vm.current_edit_member.roles_id = role_id; + if (role_id == 7){ + if(!vm.teacher){ + vm.assistant = !vm.assistant; + } + } + else if (role_id == 9){ + if(!vm.assistant){ + vm.teacher = !vm.teacher; + } + } + else if (role_id == 10){ + vm.student = !vm.student; + } } }] ); \ No newline at end of file diff --git a/public/javascripts/wechat/controllers/edit_project_member.js b/public/javascripts/wechat/controllers/edit_project_member.js index cae768080..822913f60 100644 --- a/public/javascripts/wechat/controllers/edit_project_member.js +++ b/public/javascripts/wechat/controllers/edit_project_member.js @@ -23,6 +23,7 @@ app.controller('EditProjectMemberController', ['$scope', '$http', 'auth', 'confi project_id = response.data.project_id; user_id = response.data.user_id; vm.current_edit_member = response.data.member_info; + vm.current_edit_member.roles_id = vm.current_edit_member.roles_id[0]; vm.current_roles_id = vm.current_edit_member.roles_id; } }); diff --git a/public/javascripts/wechat/controllers/join_class.js b/public/javascripts/wechat/controllers/join_class.js new file mode 100644 index 000000000..1a50080ca --- /dev/null +++ b/public/javascripts/wechat/controllers/join_class.js @@ -0,0 +1,72 @@ + + +app.controller('JoinClassController', ['$scope', '$http', 'auth', 'config', 'alertService','$location','$routeParams','rms', function($scope, $http, auth, config, alertService, $location,$routeParams, rms){ + var vm = $scope; + +// vm.current_edit_member = rms.get('current_edit_member'); + vm.current_edit_member = null; + + vm.alertService = alertService.create(); + + vm.invite_code = ""; + vm.teacher = false; //教师 + vm.assistant = false; //教辅 + vm.student = false; //学生. + + vm.cancel = function(){ +// vm.alertService.showMessage('提示', '您确定不对角色进行变更吗?', function(){ +// window.history.back(); +// }); + window.history.back(); + }; + + vm.joinClass = function(){ + if((vm.teacher == false)&& (vm.assistant == false)&&(vm.student == false)){ + vm.alertService.showMessage('提示', "请至少选择一个角色"); + return; + } + + if(vm.invite_code.length == 0) + { + vm.alertService.showMessage('提示', '请输入5位邀请码'); + return; + } + if(vm.invite_code.length != 5) + { + vm.alertService.showMessage('提示', '邀请码格式不正确'); + return; + } + + $http.post(config.apiUrl+'courses/join_class', { + token: auth.token(), + invite_code: vm.invite_code, + teacher_flag:vm.teacher, + assistant_flag:vm.assistant, + student_flag:vm.student + }).then(function(response){ + if(response.data.status == 0){ + vm.alertService.showMessage('提示', response.data.message); + $location.path("/class_list"); + } else { + vm.alertService.showMessage('提示', response.data.message); + } + }); + }; + + vm.selectRole = function(role_id){ + if (role_id == 7){ + if(!vm.teacher){ + vm.assistant = !vm.assistant; + } + } + else if (role_id == 9){ + if(!vm.assistant){ + vm.teacher = !vm.teacher; + } + } + else if (role_id == 10){ + vm.student = !vm.student; + } + } + +}] ); \ No newline at end of file diff --git a/public/javascripts/wechat/controllers/join_project.js b/public/javascripts/wechat/controllers/join_project.js new file mode 100644 index 000000000..08b84fd23 --- /dev/null +++ b/public/javascripts/wechat/controllers/join_project.js @@ -0,0 +1,52 @@ + + +app.controller('JoinProjectController', ['$scope', '$http', 'auth', 'config', 'alertService','$location','$routeParams','rms', function($scope, $http, auth, config, alertService, $location,$routeParams, rms){ + var vm = $scope; + +// vm.current_edit_member = rms.get('current_edit_member'); + + + vm.role_id = 0; + vm.alertService = alertService.create(); + + vm.cancel = function(){ + window.history.back(); + }; + + vm.join_project = function(){ + if(vm.role_id == 0){ + vm.alertService.showMessage('提示', "请至少选择一个角色"); + return; + } + + if(vm.invite_code.length == 0) + { + vm.alertService.showMessage('提示', '请输入6位邀请码'); + return; + } + if(vm.invite_code.length != 6) + { + vm.alertService.showMessage('提示', '邀请码格式不正确'); + return; + } + + + $http.post(config.apiUrl+'projects/join_project', { + token: auth.token(), + invite_code: vm.invite_code, + role_id:vm.role_id + }).then(function(response){ + if(response.data.status == 0){ + vm.alertService.showMessage('提示', response.data.message); + $location.path("/project_list"); + } else { + vm.alertService.showMessage('提示', response.data.message); + } + }); + }; + + vm.selectRole = function(role_id){ + vm.role_id = role_id; + } + +}] ); \ No newline at end of file diff --git a/public/javascripts/wechat/controllers/project_list.js b/public/javascripts/wechat/controllers/project_list.js index c5827f510..0be66cd62 100644 --- a/public/javascripts/wechat/controllers/project_list.js +++ b/public/javascripts/wechat/controllers/project_list.js @@ -47,27 +47,28 @@ app.controller('ProjectListController', ['$scope', 'config', 'auth', '$http', '$ vm.joinProject = function () { // vm.alertService_1.showMessage('提示', "该功能将在近日开放,敬请期待!"); - vm.alertService_3.showMessage('提示', '请输入6位项目邀请码(不区分大小写)', function(){ - if (vm.alertService_3.invite && vm.alertService_3.invite.length == 6) { - $http.post(config.apiUrl + "projects/join", { - token: auth.token(), - invite_code: vm.alertService_3.invite - }).then(function (response) { - console.log(response.data); - if (response.data.status != 0) { - vm.alertService_1.showMessage('提示', response.data.message); - } else { - vm.alertService_1.showMessage('提示', '加入项目成功'); - vm.alertService_3.invite = ""; - loadProjectList(); - } - }); - } else { - if(vm.alertService_3.invite){ - vm.alertService_1.showMessage('提示', '邀请码格式不正确'); - } - } - }); +// vm.alertService_3.showMessage('提示', '请输入6位项目邀请码(不区分大小写)', function(){ +// if (vm.alertService_3.invite && vm.alertService_3.invite.length == 6) { +// $http.post(config.apiUrl + "projects/join", { +// token: auth.token(), +// invite_code: vm.alertService_3.invite +// }).then(function (response) { +// console.log(response.data); +// if (response.data.status != 0) { +// vm.alertService_1.showMessage('提示', response.data.message); +// } else { +// vm.alertService_1.showMessage('提示', '加入项目成功'); +// vm.alertService_3.invite = ""; +// loadProjectList(); +// } +// }); +// } else { +// if(vm.alertService_3.invite){ +// vm.alertService_1.showMessage('提示', '邀请码格式不正确'); +// } +// } +// }); + $location.path("/join_project"); }; vm.onSetting = function (project) { diff --git a/public/javascripts/wechat/controllers/review_class_member.js b/public/javascripts/wechat/controllers/review_class_member.js new file mode 100644 index 000000000..68f715447 --- /dev/null +++ b/public/javascripts/wechat/controllers/review_class_member.js @@ -0,0 +1,68 @@ + + +app.controller('ReviewClassMemberController', ['$scope', '$http', 'auth', 'config', 'alertService','$location','$routeParams','rms', function($scope, $http, auth, config, alertService, $location,$routeParams, rms){ + var vm = $scope; + +// vm.current_edit_member = rms.get('current_edit_member'); + + vm.current_review_member = rms.get('current_review_member'); + vm.current_course = rms.get('current_course'); + + vm.alertService = alertService.create(); + + var course_id = $routeParams.id; + var user_id = $routeParams.user_id; + + if(!vm.current_course){ + $http.get(config.apiUrl+ 'courses/'+course_id+"?token="+auth.token()).then( + function(response) { + console.log(response.data); + if (response.data.status == 0){ + vm.current_course = response.data.data; + console.log("courses"); + console.log(response.data.data); + } + else{ + vm.alertService.showMessage('提示', response.data.message); + } + + } + ); + } + + if(!vm.current_review_member){ + $http.post(config.apiUrl+'courses/review_member_info', { + token: auth.token(), + course_id: course_id, + user_id:user_id + }).then(function(response){ + if(response.data.status!=0){ + vm.alertService.showMessage('提示', response.data.message); + } else { + vm.current_review_member = response.data.data; + console.log("review_member_info"); + console.log(response.data.data); + } + }); + + + } + + vm.deal = function(result){ + $http.post(config.apiUrl+'courses/deal_join_apply', { + token: auth.token(), + course_id: course_id, + user_id:user_id, + type:result + }).then(function(response) { + if (response.data.status == 0) { + vm.alertService.showMessage('提示', response.data.message, function () { + $location.path("/class_list"); + }); + } + else{ + vm.alertService.showMessage('提示', response.data.message); + } + }); + }; +}] ); \ No newline at end of file diff --git a/public/javascripts/wechat/controllers/review_project_member.js b/public/javascripts/wechat/controllers/review_project_member.js new file mode 100644 index 000000000..3d9485dc3 --- /dev/null +++ b/public/javascripts/wechat/controllers/review_project_member.js @@ -0,0 +1,109 @@ + + +app.controller('ReviewProjectMemberController', ['$scope', '$http', 'auth', 'config', 'alertService','$location','$routeParams','rms', function($scope, $http, auth, config, alertService, $location,$routeParams, rms){ + var vm = $scope; + +// vm.current_edit_member = rms.get('current_edit_member'); + vm.current_edit_member = null; + + vm.alertService = alertService.create(); + + var course_id = $routeParams.id; + var user_id = $routeParams.user_id; + + vm.teacher = false; //教师 + vm.assistant = false; //教辅 + vm.student = false; //学生. + + vm.tmpteacher = false; //教师 + vm.tmpassistant = false; //教辅 + vm.tmpstudent = false; //学生 + + + if(!vm.current_edit_member){ + $http.post(config.apiUrl+'courses/get_member_info', { + token: auth.token(), + id: course_id, + user_id:user_id + }).then(function(response){ + if(response.data.status!=0){ + vm.alertService.showMessage('提示', response.data.message); + } else { + console.log(response); + course_id = response.data.course_id; + user_id = response.data.user_id; + vm.current_edit_member = response.data.member_info; + vm.current_roles_id = vm.current_edit_member.roles_id; + + for(var i in vm.current_roles_id){ + if(vm.current_roles_id[i] == 9){ + vm.teacher = true; + vm.tmpteacher = true; + } + else if(vm.current_roles_id[i] == 7){ + vm.assistant = true; + vm.tmpassistant = true; + } + else if(vm.current_roles_id[i] == 10){ + vm.student = true; + vm.tmpstudent = true; + } + } + } + }); + } + + vm.cancel = function(){ +// vm.alertService.showMessage('提示', '您确定不对角色进行变更吗?', function(){ +// window.history.back(); +// }); + window.history.back(); + }; + + vm.edit_member_role = function(){ + if((vm.teacher == vm.tmpteacher)&& (vm.assistant == vm.tmpassistant)&&(vm.student == vm.tmpstudent)){ + vm.alertService.showMessage('提示', "该用户当前已是该角色"); + return; + } + + if((vm.teacher == false)&& (vm.assistant == false)&&(vm.student == false)){ + vm.alertService.showMessage('提示', "请至少选择一种角色"); + return; + } + + $http.post(config.apiUrl+'courses/edit_member_role', { + token: auth.token(), + id: course_id, + user_id:vm.current_edit_member.user.id, + teacher_flag:vm.teacher, + assistant_flag:vm.assistant, + student_flag:vm.student + }).then(function(response){ + if(response.data.status!=0){ + vm.alertService.showMessage('提示', response.data.message); + } else { + vm.alertService.showMessage('提示', '修改角色成功', function(){ +// window.history.back(); + $location.path("/class").search({id: course_id,tag:1}); + }); + } + }); + }; + + vm.selectRole = function(role_id){ + if (role_id == 7){ + if(!vm.teacher){ + vm.assistant = !vm.assistant; + } + } + else if (role_id == 9){ + if(!vm.assistant){ + vm.teacher = !vm.teacher; + } + } + else if (role_id == 10){ + vm.student = !vm.student; + } + } + +}] ); \ No newline at end of file diff --git a/public/javascripts/wechat/others/routes.js b/public/javascripts/wechat/others/routes.js index 8596ee706..70d1491f4 100644 --- a/public/javascripts/wechat/others/routes.js +++ b/public/javascripts/wechat/others/routes.js @@ -38,11 +38,15 @@ app.config(['$routeProvider',"$httpProvider", "$locationProvider",'config', func .when('/myresource', makeRoute('myresource.html', 'MyResourceController')) .when('/invite_code', {templateUrl: rootPath + 'invite_code.html', controller: 'InviteCodeController'}) .when('/send_class_list', makeRoute('send_class_list.html', 'SendClassListController')) + .when('/join_class', makeRoute('join_class.html', 'JoinClassController')) + .when('/review_class_member', makeRoute('review_class_member.html', 'ReviewClassMemberController')) .when('/project_list', makeRoute('project_list.html', 'ProjectListController')) .when('/project', makeRoute('project.html', 'ProjectController')) .when('/edit_project_member', makeRoute('edit_project_member.html', 'EditProjectMemberController')) .when('/new_project', makeRoute('new_project.html', 'NewProjectController')) .when('/project_invite_code', {templateUrl: rootPath + 'project_invite_code.html', controller: 'ProjectInviteCodeController'}) + .when('/join_project', makeRoute('join_project.html', 'JoinProjectController')) + .when('/review_project_member', makeRoute('review_project_member.html', 'ReviewProjectMemberController')) .otherwise({ redirectTo: '/activites' }); From 2632f7aa593d132a1c90b3eb640e789be089cc74 Mon Sep 17 00:00:00 2001 From: guange <8863824@gmail.com> Date: Tue, 2 Aug 2016 17:01:10 +0800 Subject: [PATCH 26/78] =?UTF-8?q?=E5=BC=95=E5=85=A5wechat=20js=20sdk?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/wechats_controller.rb | 11 +++++++++++ app/views/wechats/user_activities.html.erb | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/app/controllers/wechats_controller.rb b/app/controllers/wechats_controller.rb index 87ede1365..190502a3c 100644 --- a/app/controllers/wechats_controller.rb +++ b/app/controllers/wechats_controller.rb @@ -383,7 +383,15 @@ class WechatsController < ActionController::Base render 'wechats/user_activities', layout: nil end + + def user_activities + + @appid = Wechat.config.appid + ## sign + + @sign_params = wechat.jsapi_ticket.signature(current_url) + session[:wechat_code] = params[:code] if params[:code] @path = '/'+(params[:state] || '') open_id = get_openid_from_code(params[:code]) rescue @@ -431,6 +439,9 @@ class WechatsController < ActionController::Base uw = UserWechat.where(openid: openid).first end + def current_url + "#{request.protocol}#{request.host_with_port}#{request.fullpath}" + end end diff --git a/app/views/wechats/user_activities.html.erb b/app/views/wechats/user_activities.html.erb index f5cfb8250..e06d84bfb 100644 --- a/app/views/wechats/user_activities.html.erb +++ b/app/views/wechats/user_activities.html.erb @@ -12,6 +12,7 @@ <%= stylesheet_link_tag '/stylesheets/weui/weixin.css' %> + From 2a67ec5407defd7a748a5e5c41ad954391bb2185 Mon Sep 17 00:00:00 2001 From: guange <8863824@gmail.com> Date: Tue, 2 Aug 2016 17:27:40 +0800 Subject: [PATCH 27/78] =?UTF-8?q?=E9=85=8D=E7=BD=AE=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E9=A1=B5=E8=8F=9C=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/wechats/user_activities.html.erb | 5 ++++- public/javascripts/wechat/controllers/login.js | 7 +++++-- public/javascripts/wechat/others/factory.js | 4 ++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/app/views/wechats/user_activities.html.erb b/app/views/wechats/user_activities.html.erb index e06d84bfb..e7b89f224 100644 --- a/app/views/wechats/user_activities.html.erb +++ b/app/views/wechats/user_activities.html.erb @@ -23,6 +23,8 @@ window.g_projectid = <%= @project_id %>; <% end %> + //参考文档 + //https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&lang=zh_CN wx.config({ debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: '<%= @appid %>', // 必填,公众号的唯一标识 @@ -30,7 +32,8 @@ nonceStr: '<%= @sign_params[:noncestr] %>', // 必填,生成签名的随机串 signature: '<%= @sign_params[:signature] %>',// 必填,签名,见附录1 jsApiList: ['onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareWeibo', 'onMenuShareQZone', - 'hideMenuItems','closeWindow', 'scanQRCode'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 + 'hideOptionMenu','showOptionMenu','showMenuItems', 'hideMenuItems', + 'hideAllNonBaseMenuItem','showAllNonBaseMenuItem','closeWindow', 'scanQRCode'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function(){ diff --git a/public/javascripts/wechat/controllers/login.js b/public/javascripts/wechat/controllers/login.js index f31dd629f..b70398955 100644 --- a/public/javascripts/wechat/controllers/login.js +++ b/public/javascripts/wechat/controllers/login.js @@ -1,5 +1,8 @@ -app.controller('LoginController', ['$scope', '$http', '$location', '$routeParams', 'alertService', 'config','auth','session', - function ($scope, $http, $location, $routeParams, alertService, config, auth,session) { +app.controller('LoginController', ['$scope', '$http', '$location', '$routeParams', 'alertService', 'config','auth','session','wx', + function ($scope, $http, $location, $routeParams, alertService, config, auth,session, wx) { + // 登录页不用显示菜音 + wx.hideOptionMenu(); + if(auth.get_bind().then(function(){ $location.path("/activities"); })); diff --git a/public/javascripts/wechat/others/factory.js b/public/javascripts/wechat/others/factory.js index 89e2b700f..6e110a6ea 100644 --- a/public/javascripts/wechat/others/factory.js +++ b/public/javascripts/wechat/others/factory.js @@ -30,6 +30,10 @@ app.factory('alertService', function(){ } }); +app.factory('wx', ['$window', function($window){ + var wechat = $window.wx; + return wechat; +}]); app.factory('auth', ['$http','$routeParams', '$q', 'session', 'config',function($http,$routeParams, $q, session,config){ //是否已经绑定 From 56d6f4b9bc308d200716e6a1f42983d71b469729 Mon Sep 17 00:00:00 2001 From: guange <8863824@gmail.com> Date: Tue, 2 Aug 2016 17:36:59 +0800 Subject: [PATCH 28/78] =?UTF-8?q?=E5=AE=9A=E5=88=B6=E5=88=86=E4=BA=AB?= =?UTF-8?q?=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wechat/controllers/invite_code.js | 16 +++++++++++++++- public/javascripts/wechat/controllers/login.js | 5 ++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/public/javascripts/wechat/controllers/invite_code.js b/public/javascripts/wechat/controllers/invite_code.js index ca69e308c..ec0a3ee65 100644 --- a/public/javascripts/wechat/controllers/invite_code.js +++ b/public/javascripts/wechat/controllers/invite_code.js @@ -3,9 +3,23 @@ */ -app.controller('InviteCodeController', ['$scope','$http', '$routeParams','config','auth', function($scope, $http, $routeParams, config, auth){ +app.controller('InviteCodeController', ['$scope','$http', '$routeParams','config','auth','wx', function($scope, $http, $routeParams, config, auth, wx){ var vm = $scope; + wx.ready(function(){ + wx.onMenuShareTimeline({ + title: '定制的标题', // 分享标题 + link: 'http://www.baidu.com', // 分享链接 + imgUrl: 'https://rescdn.qqmail.com/zh_CN/htmledition/images/webp/spacer1e9c5d.gif', // 分享图标 + success: function () { + console.log("share successed."); + }, + cancel: function () { + console.log("share canceled."); + } + }); + }); + vm.course = {}; var courseid = $routeParams.id; $http.get(config.apiUrl+ 'courses/'+courseid+"?token="+auth.token()).then( diff --git a/public/javascripts/wechat/controllers/login.js b/public/javascripts/wechat/controllers/login.js index b70398955..863af07ee 100644 --- a/public/javascripts/wechat/controllers/login.js +++ b/public/javascripts/wechat/controllers/login.js @@ -1,7 +1,10 @@ app.controller('LoginController', ['$scope', '$http', '$location', '$routeParams', 'alertService', 'config','auth','session','wx', function ($scope, $http, $location, $routeParams, alertService, config, auth,session, wx) { + // 登录页不用显示菜音 - wx.hideOptionMenu(); + wx.ready(function(){ + wx.hideOptionMenu(); + }) if(auth.get_bind().then(function(){ $location.path("/activities"); From 6f2b84570ff550703dda9a5a0df22e440434233d Mon Sep 17 00:00:00 2001 From: guange <8863824@gmail.com> Date: Tue, 2 Aug 2016 17:48:51 +0800 Subject: [PATCH 29/78] =?UTF-8?q?=E5=8E=BB=E9=99=A4=E8=B0=83=E8=AF=95?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/wechats/user_activities.html.erb | 2 +- public/javascripts/wechat/controllers/invite_code.js | 4 ++-- public/javascripts/wechat/controllers/login.js | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/app/views/wechats/user_activities.html.erb b/app/views/wechats/user_activities.html.erb index e7b89f224..ac3b845ff 100644 --- a/app/views/wechats/user_activities.html.erb +++ b/app/views/wechats/user_activities.html.erb @@ -26,7 +26,7 @@ //参考文档 //https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&lang=zh_CN wx.config({ - debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 + debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: '<%= @appid %>', // 必填,公众号的唯一标识 timestamp: <%= @sign_params[:timestamp] %>, // 必填,生成签名的时间戳 nonceStr: '<%= @sign_params[:noncestr] %>', // 必填,生成签名的随机串 diff --git a/public/javascripts/wechat/controllers/invite_code.js b/public/javascripts/wechat/controllers/invite_code.js index ec0a3ee65..0467dee5d 100644 --- a/public/javascripts/wechat/controllers/invite_code.js +++ b/public/javascripts/wechat/controllers/invite_code.js @@ -9,8 +9,8 @@ app.controller('InviteCodeController', ['$scope','$http', '$routeParams','config wx.ready(function(){ wx.onMenuShareTimeline({ title: '定制的标题', // 分享标题 - link: 'http://www.baidu.com', // 分享链接 - imgUrl: 'https://rescdn.qqmail.com/zh_CN/htmledition/images/webp/spacer1e9c5d.gif', // 分享图标 + link: 'http://wechat.trustie.net/', // 分享链接 + imgUrl: 'http://wechat.trustie.net/images/logo2.png', // 分享图标 success: function () { console.log("share successed."); }, diff --git a/public/javascripts/wechat/controllers/login.js b/public/javascripts/wechat/controllers/login.js index 863af07ee..f8e87a93f 100644 --- a/public/javascripts/wechat/controllers/login.js +++ b/public/javascripts/wechat/controllers/login.js @@ -39,8 +39,7 @@ app.controller('LoginController', ['$scope', '$http', '$location', '$routeParams vm.loginFailed = (response.data.status != 0); if (!$scope.loginFailed) { //绑定成功 vm.alertService.showMessage('提示', response.data.message, function(){ -// $location.path("/activities"); - window.WeixinJSBridge.call('closeWindow'); + wx.closeWindow(); }); } else { vm.alertService.showMessage('出错了', response.data.message); From 4ab2427827365d3b065204710f295312db0e2071 Mon Sep 17 00:00:00 2001 From: yuanke <249218296@qq.com> Date: Wed, 3 Aug 2016 09:37:24 +0800 Subject: [PATCH 30/78] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E5=8F=8A=E8=AF=BE=E7=A8=8B=E7=94=B3=E8=AF=B7=E5=AE=A1=E6=A0=B8?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/mobile/apis/projects.rb | 47 +++++++ app/api/mobile/entities/project.rb | 4 +- app/models/applied_project.rb | 8 ++ app/services/courses_service.rb | 2 +- app/services/projects_service.rb | 95 +++++++++++++- app/services/wechat_service.rb | 35 +++++- config/wechat.yml.template | 2 +- config/wechat.yml.test | 1 + public/assets/wechat/project.html | 13 +- .../assets/wechat/review_project_member.html | 11 +- .../javascripts/wechat/controllers/project.js | 15 +++ .../controllers/review_project_member.js | 117 ++++++------------ 12 files changed, 252 insertions(+), 98 deletions(-) diff --git a/app/api/mobile/apis/projects.rb b/app/api/mobile/apis/projects.rb index f3242845f..04863c6e5 100644 --- a/app/api/mobile/apis/projects.rb +++ b/app/api/mobile/apis/projects.rb @@ -86,9 +86,24 @@ module Mobile develop_members = project.member_principals.includes(:roles, :principal).where("member_roles.role_id=4").all.sort report_members = project.member_principals.includes(:roles, :principal).where("member_roles.role_id=5").all.sort + review_master_members = [] + review_develop_members = [] + + my_member = project.member_principals.where("users.id=#{current_user.id}").first + if my_member && my_member.roles[0] && my_member.roles[0].id == 3 + ps = ProjectsService.new + + user = current_user + review_master_members = ps.get_project_review_members(project,3,user) + review_develop_members = ps.get_project_review_members(project,4,user) + + end + present :master_members,master_members, with: Mobile::Entities::ProjectMember present :develop_members,develop_members, with: Mobile::Entities::ProjectMember present :report_members,report_members, with: Mobile::Entities::ProjectMember + present :report_members,review_master_members + present :report_members,review_develop_members present :status, 0 end @@ -182,6 +197,38 @@ module Mobile # {status:-1, message: '该功能将在近日开放,敬请期待!' } end + desc "项目单个未审核用户信息" + params do + requires :token, type: String + requires :project_id, type: Integer, desc: "项目id" + requires :user_id, type: Integer, desc: "用户id" + end + post 'review_member_info' do + authenticate! + + ps = ProjectsService.new + reviewer = ps.get_reviewer_info(params) + present :data, reviewer, with: Mobile::Entities::User + present :status, 0 + end + + desc "处理管理或开发的身份申请" + params do + requires :token, type: String + requires :project_id, type: Integer, desc: "项目id" + requires :user_id, type: Integer, desc: "用户id" + requires :type, type: Integer, desc: "同意或拒绝" + end + post 'deal_join_apply' do + authenticate! + + ps = ProjectsService.new + result = ps.deal_join_apply(params,current_user) + + present :status, result[:status] + present :message, result[:message] + end + end end end diff --git a/app/api/mobile/entities/project.rb b/app/api/mobile/entities/project.rb index 073f7cd0f..3e1899caa 100644 --- a/app/api/mobile/entities/project.rb +++ b/app/api/mobile/entities/project.rb @@ -4,8 +4,8 @@ module Mobile expose :name expose :id expose :user_id - expose :invite_code - expose :qrcode + # expose :invite_code + # expose :qrcode expose :can_setting, if: lambda { |instance, options| options[:user] } do |instance, options| current_user = options[:user] diff --git a/app/models/applied_project.rb b/app/models/applied_project.rb index b1945a937..7597778f8 100644 --- a/app/models/applied_project.rb +++ b/app/models/applied_project.rb @@ -11,6 +11,14 @@ class AppliedProject < ActiveRecord::Base def send_appliled_message self.project.managers.each do |member| self.applied_messages << AppliedMessage.new(:user_id => member.user_id, :status => true, :viewed => false, :applied_user_id => self.user_id, :role => self.role, :project_id => self.project_id) + + #----------------微信通知---------------------- + count = ShieldWechatMessage.where("container_type='User' and container_id=#{member.user_id} and shield_type='Project' and shield_id=#{self.project_id}").count + if count == 0 + ws = WechatService.new + ws.project_review_notice member.user_id, "review_project_member", self.project_id, "项目成员审批通知", self.project.name, self.user.show_name, format_time(Time.now),"点击查看申请详情。",self.user.id + end + #-------------------------------------------- end # end end diff --git a/app/services/courses_service.rb b/app/services/courses_service.rb index c8401f051..ccae53b45 100644 --- a/app/services/courses_service.rb +++ b/app/services/courses_service.rb @@ -605,7 +605,7 @@ class CoursesService rolename = role_ids.include?("7") ? "助教" : "教师" content = current_user.show_name + "申请以"+rolename+"身份加入班级,等待您的审批。" ws = WechatService.new - ws.class_notice tea_user.id, "course_join_review", course.id, "班级成员审批通知", course.name, tea_user.show_name, format_time(Time.now), content, "点击查看申请详情" + ws.class_notice tea_user.id, "review_class_member", course.id, "班级成员审批通知", course.name, tea_user.show_name, format_time(Time.now), content, "点击查看申请详情。",current_user.id end end #-------------------------------------------- diff --git a/app/services/projects_service.rb b/app/services/projects_service.rb index f519059d2..3dbf299c2 100644 --- a/app/services/projects_service.rb +++ b/app/services/projects_service.rb @@ -13,8 +13,8 @@ class ProjectsService #显示项目 def show_project(params,current_user) project = Project.find(params[:id]) - project.generate_invite_code - project.generate_qrcode + # project.generate_invite_code + # project.generate_qrcode project end @@ -108,6 +108,8 @@ class ProjectsService 4, '您已经是该项目的开发人员', 5, '您已经是该项目的报告人员', 6, '该项目不存在或已被删除啦', + 7, '您的申请已提交,请等待管理员审批', + 8, '您已经发送过申请了,请耐心等待', '未知错误,请稍后再试' ] end @@ -142,7 +144,13 @@ class ProjectsService status = 0 else + if !AppliedProject.where(:project_id => project.id, :user_id => current_user.id).first.nil? + status = 8 + else + AppliedProject.create(:user_id => current_user.id, :project_id => project.id, :role => params[:role_id]) + status = 7 + end end else status = 4 @@ -155,4 +163,87 @@ class ProjectsService status end + def get_project_review_members(project,role_id,current_user) + review_members = [] + + if role_id == 3 || role_id == 4 + + #AppliedMessage.where(:applied_id => @applied_message.applied_id, :project_id => @applied_message.project_id, :status => 1, + #:applied_type => "AppliedProject") + + + apply_messages = AppliedMessage.where(:user_id => current_user.id, :project_id => project.id, :status => 1, :role=>role_id) + + apply_messages.each do |m| + user = User.find(m.applied_user_id) + + if user + img_url = url_to_avatar(user) + gender = user.user_extensions.gender.nil? ? 0 : user.user_extensions.gender + work_unit = get_user_work_unit user + location = get_user_location user + review_members << {:id => user.id, :img_url => img_url, :nickname => user.login, :gender => gender, + :work_unit => work_unit, :mail => user.mail, :location => location, + role_name: "", + name: user.show_name, + roles_id: role_id, + :brief_introduction => user.user_extensions.brief_introduction,:realname=>user.realname} + end + end + end + + review_members + end + + def get_reviewer_info params + info = nil + project = Project.find(params[:project_id]) + if project + messages = AppliedProject.where("project_id = ? and user_id=?",project.id,params[:user_id]).first + + if messages + user = User.find(params[:user_id]) + if user + img_url = url_to_avatar(user) + gender = user.user_extensions.gender.nil? ? 0 : user.user_extensions.gender + work_unit = get_user_work_unit user + location = get_user_location user + info = {:id => user.id, :img_url => img_url, :nickname => user.login, :gender => gender, + :work_unit => work_unit, :mail => user.mail, :location => location, + role_name: "", + name: user.show_name, + roles_id: messages.role_id, + :brief_introduction => user.user_extensions.brief_introduction,:realname=>user.realname} + end + end + end + + info + end + + def deal_join_apply params,current_user + status = -1 + message = "" + + project = Project.find(params[:project_id]) + + if project + messages = AppliedProject.where("project_id = ? and user_id=?",project.id,params[:user_id]).first + if messages + apply_user = User.find(params[:user_id]) + + # + + + status = 0 + else + message = "该申请不存在或已被处理" + end + else + message = "该班级不存在或已被删除" + end + + {:status => status,:message => message} + end + end diff --git a/app/services/wechat_service.rb b/app/services/wechat_service.rb index 5f52aea49..d2dc683fd 100644 --- a/app/services/wechat_service.rb +++ b/app/services/wechat_service.rb @@ -139,11 +139,16 @@ class WechatService data end - def three_keys_template(openid, template_id, type, id, first, key1, key2, key3, remark="") + def three_keys_template(openid, template_id, type, id, first, key1, key2, key3, remark="",uid) + tmpurl = "#{Setting.protocol}://#{Setting.host_name}/wechat/user_activities#/#{type}/#{id}" + if uid && uid != 0 + tmpurl = tmpurl + "&user_id="+uid + end + data = { touser:openid, template_id:template_id, - url:"#{Setting.protocol}://#{Setting.host_name}/wechat/user_activities#/#{type}/#{id}",#/assets/wechat/app.html#/#{type}/#{id} + url:tmpurl,#/assets/wechat/app.html#/#{type}/#{id} topcolor:"#FF0000", data:{ first: { @@ -171,11 +176,16 @@ class WechatService data end - def four_keys_template(openid, template_id, type, id, first, key1, key2, key3, key4, remark="") + def four_keys_template(openid, template_id, type, id, first, key1, key2, key3, key4, remark="",uid) + tmpurl = "#{Setting.protocol}://#{Setting.host_name}/wechat/user_activities#/#{type}/#{id}" + if uid && uid != 0 + tmpurl = tmpurl + "&user_id="+uid + end + data = { touser:openid, template_id:template_id, - url:"#{Setting.protocol}://#{Setting.host_name}/wechat/user_activities#/#{type}/#{id}", #/assets/wechat/app.html#/#{type}/#{id} + url:tmpurl, #/assets/wechat/app.html#/#{type}/#{id} topcolor:"#FF0000", data:{ first: { @@ -269,10 +279,10 @@ class WechatService end end - def class_notice(user_id, type, id, first, key1, key2, key3, key4, remark="") + def class_notice(user_id, type, id, first, key1, key2, key3, key4, remark="",uid=0) uw = UserWechat.where(user_id: user_id).first unless uw.nil? - data = four_keys_template uw.openid,Wechat.config.class_notice, type, id, first, key1, key2, key3, key4, remark + data = four_keys_template uw.openid,Wechat.config.class_notice, type, id, first, key1, key2, key3, key4, remark, uid begin req = Wechat.api.template_message_send Wechat::Message.to(uw.openid).template(data) rescue Exception => e @@ -360,4 +370,17 @@ class WechatService end end + def project_review_notice(user_id, type, id, first, key1, key2,key3,remark="",uid=0) + uw = UserWechat.where(user_id: user_id).first + unless uw.nil? + data = three_keys_template uw.openid,Wechat.config.project_review_notice, type, id, first, key1, key2, key3, remark,uid + begin + req = Wechat.api.template_message_send Wechat::Message.to(uw.openid).template(data) + rescue Exception => e + Rails.logger.error "[project_review_notice] ===> #{e}" + end + Rails.logger.info "send over. #{req}" + end + end + end \ No newline at end of file diff --git a/config/wechat.yml.template b/config/wechat.yml.template index 02ec8db55..68e6ed62e 100644 --- a/config/wechat.yml.template +++ b/config/wechat.yml.template @@ -22,7 +22,7 @@ default: &default class_notice: "MQ_mFupbXP-9jWbeHT3C5xqNBvPo8EIlNv4ULakSpJA" create_class_notice: "2GtJJGzzNlNy2i0UrsjEDlvfSVIUXQfSo47stpcQAVw" create_project_notice: "jYu0iimbDpgWYZaTLXioZe2lvqoWTdKnUPyphTJ1mxs" - + project_review_notice: "kdb-8UlMjTc3z51Qcf8g2vY4i_nE4OGKZAucdQma_2E" production: <<: *default diff --git a/config/wechat.yml.test b/config/wechat.yml.test index ec5e760fa..3d1861d67 100644 --- a/config/wechat.yml.test +++ b/config/wechat.yml.test @@ -22,6 +22,7 @@ default: &default class_notice: "8LVu33l6bP-56SDomVgHn-yJc57YpCwwJ81rAJgRONk" create_class_notice: "9CDIvHIKiGwPEQWRw_-wieec1o50tMXQPPZIfECKu0I" create_project_notice: "R2ZaQKJfDJgujPcHWPzadKHIRkIyj2CjX2o_qIuRqig" + project_review_notice: "cwpAHzdrYQo0Gc5ZKCBHMYEe8NjlOF6KpMGklMch8RM" production: <<: *default diff --git a/public/assets/wechat/project.html b/public/assets/wechat/project.html index 76ebc0430..1ec43de2c 100644 --- a/public/assets/wechat/project.html +++ b/public/assets/wechat/project.html @@ -110,16 +110,27 @@
      管理人员({{project_master_members.length}})
      - {{master.user.real_name == "" ? master.user.name : master.user.real_name }}{{teacher.role_name|identify}} + {{master.user.real_name == "" ? master.user.name : master.user.real_name }}
      +
      + {{user.real_name == "" ? user.name : user.real_name }} + 待审批 +
      +
      +
      开发人员({{project_develop_members.length}})
      {{develop.user.real_name == "" ? develop.user.name : develop.user.real_name}}
      +
      + {{user.real_name == "" ? user.name : user.real_name}} + 待审批 +
      +
      报告人员({{project_report_members.length}})
      {{report.user.real_name == "" ? report.user.name : report.user.real_name}} diff --git a/public/assets/wechat/review_project_member.html b/public/assets/wechat/review_project_member.html index 1e556780b..a2b888482 100644 --- a/public/assets/wechat/review_project_member.html +++ b/public/assets/wechat/review_project_member.html @@ -1,17 +1,16 @@
      -
      角色变更
      +
      {{project.name}}
      项目邀请码
      角色
        -
      • -
      • -
      • +
      • +
      diff --git a/public/javascripts/wechat/controllers/project.js b/public/javascripts/wechat/controllers/project.js index c4ff551a6..eded4ecc7 100644 --- a/public/javascripts/wechat/controllers/project.js +++ b/public/javascripts/wechat/controllers/project.js @@ -19,6 +19,12 @@ app.controller('ProjectController', ['$scope', 'config','$http','$timeout', 'aut vm.project_develop_members = rms.get("project_develop_members") || []; vm.project_report_members = rms.get("project_report_members") || []; +// vm.review_master_members = rms.get("review_master_members") || []; +// vm.review_develop_members = rms.get("review_master_members") || []; + + vm.review_master_members = []; + vm.review_develop_members = []; + // vm.project_members_has_more = rms.get("project_members_has_more"); vm.alertService = alertService.create(); @@ -82,6 +88,8 @@ app.controller('ProjectController', ['$scope', 'config','$http','$timeout', 'aut vm.project_develop_members = response.data.develop_members; vm.project_report_members = response.data.report_members; + vm.review_master_members = response.data.review_master_members; + vm.review_develop_members = response.data.review_develop_members; } else{ vm.alertService.showMessage('提示', response.data.message); @@ -201,4 +209,11 @@ app.controller('ProjectController', ['$scope', 'config','$http','$timeout', 'aut $location.path("/edit_project_member").search({id: projectid,user_id: data.user.id}); }; + vm.review = function(user){ + rms.save('current_review_member', user); + rms.save('current_project', vm.project); + + $location.path("/review_project_member").search({id: projectid,user_id: user.id}); + } + }]); \ No newline at end of file diff --git a/public/javascripts/wechat/controllers/review_project_member.js b/public/javascripts/wechat/controllers/review_project_member.js index 3d9485dc3..f5b554832 100644 --- a/public/javascripts/wechat/controllers/review_project_member.js +++ b/public/javascripts/wechat/controllers/review_project_member.js @@ -4,106 +4,65 @@ app.controller('ReviewProjectMemberController', ['$scope', '$http', 'auth', 'con var vm = $scope; // vm.current_edit_member = rms.get('current_edit_member'); - vm.current_edit_member = null; + + vm.current_review_member = rms.get('current_review_member'); + vm.current_project = rms.get('current_project'); vm.alertService = alertService.create(); - var course_id = $routeParams.id; + var project_id = $routeParams.id; var user_id = $routeParams.user_id; - vm.teacher = false; //教师 - vm.assistant = false; //教辅 - vm.student = false; //学生. - - vm.tmpteacher = false; //教师 - vm.tmpassistant = false; //教辅 - vm.tmpstudent = false; //学生 + if(!vm.current_course){ + $http.get(config.apiUrl+ 'projects/'+project_id+"?token="+auth.token()).then( + function(response) { + console.log(response.data); + if (response.data.status == 0){ + vm.current_project = response.data.data; + console.log("projects"); + console.log(response.data.data); + } + else{ + vm.alertService.showMessage('提示', response.data.message); + } + } + ); + } - if(!vm.current_edit_member){ - $http.post(config.apiUrl+'courses/get_member_info', { + if(!vm.current_review_member){ + $http.post(config.apiUrl+'projects/review_member_info', { token: auth.token(), - id: course_id, + project_id: project_id, user_id:user_id }).then(function(response){ if(response.data.status!=0){ vm.alertService.showMessage('提示', response.data.message); } else { - console.log(response); - course_id = response.data.course_id; - user_id = response.data.user_id; - vm.current_edit_member = response.data.member_info; - vm.current_roles_id = vm.current_edit_member.roles_id; - - for(var i in vm.current_roles_id){ - if(vm.current_roles_id[i] == 9){ - vm.teacher = true; - vm.tmpteacher = true; - } - else if(vm.current_roles_id[i] == 7){ - vm.assistant = true; - vm.tmpassistant = true; - } - else if(vm.current_roles_id[i] == 10){ - vm.student = true; - vm.tmpstudent = true; - } - } + vm.current_review_member = response.data.data; + console.log("review_member_info"); + console.log(response.data.data); } }); - } - vm.cancel = function(){ -// vm.alertService.showMessage('提示', '您确定不对角色进行变更吗?', function(){ -// window.history.back(); -// }); - window.history.back(); - }; - - vm.edit_member_role = function(){ - if((vm.teacher == vm.tmpteacher)&& (vm.assistant == vm.tmpassistant)&&(vm.student == vm.tmpstudent)){ - vm.alertService.showMessage('提示', "该用户当前已是该角色"); - return; - } - if((vm.teacher == false)&& (vm.assistant == false)&&(vm.student == false)){ - vm.alertService.showMessage('提示', "请至少选择一种角色"); - return; - } + } - $http.post(config.apiUrl+'courses/edit_member_role', { + vm.deal = function(result){ + $http.post(config.apiUrl+'projects/deal_join_apply', { token: auth.token(), - id: course_id, - user_id:vm.current_edit_member.user.id, - teacher_flag:vm.teacher, - assistant_flag:vm.assistant, - student_flag:vm.student - }).then(function(response){ - if(response.data.status!=0){ - vm.alertService.showMessage('提示', response.data.message); - } else { - vm.alertService.showMessage('提示', '修改角色成功', function(){ -// window.history.back(); - $location.path("/class").search({id: course_id,tag:1}); + project_id: project_id, + user_id:user_id, + type:result + }).then(function(response) { + if (response.data.status == 0) { + vm.alertService.showMessage('提示', response.data.message, function () { + $location.path("/project_list"); }); } + else{ + vm.alertService.showMessage('提示', response.data.message); + } }); }; - - vm.selectRole = function(role_id){ - if (role_id == 7){ - if(!vm.teacher){ - vm.assistant = !vm.assistant; - } - } - else if (role_id == 9){ - if(!vm.assistant){ - vm.teacher = !vm.teacher; - } - } - else if (role_id == 10){ - vm.student = !vm.student; - } - } - }] ); \ No newline at end of file From 5f969c6593011ba1aafe4b15ef0682ac9d930288 Mon Sep 17 00:00:00 2001 From: daiao <358551898@qq.com> Date: Wed, 3 Aug 2016 10:36:03 +0800 Subject: [PATCH 31/78] =?UTF-8?q?=E5=8D=95=E4=BD=8D=E5=AE=A1=E6=A0=B8?= =?UTF-8?q?=E7=9B=B8=E5=85=B3Bug=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/admin_controller.rb | 18 +++++------------- app/views/admin/_all_schools.html.erb | 2 ++ app/views/admin/all_schools.js.erb | 16 ++++++++-------- app/views/admin/applied_schools.html.erb | 4 ++-- app/views/admin/has_applied_schools.html.erb | 4 ++-- app/views/my/account.html.erb | 10 +++++----- app/views/users/_user_message_applied.html.erb | 12 ++++++------ public/javascripts/application.js | 2 ++ 8 files changed, 32 insertions(+), 36 deletions(-) diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb index c98116806..2e51d6a03 100644 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/admin_controller.rb @@ -674,9 +674,7 @@ class AdminController < ApplicationController aas.update_attribute(:status, 2) AppliedMessage.create(:user_id => aas.user_id, :status => 2, :viewed => true, :applied_id => aas.id, :applied_type => "ApplyAddSchools", :name => school[0].name ) users = UserExtensions.where("school_id = #{aas.school_id}") - users.each do |user| - user.update_column("school_id", school[0].id) - end + users.update_all(:school_id => school[0].id) if aas.school_id != school[0].id.to_i aas.school.destroy end @@ -717,20 +715,14 @@ class AdminController < ApplicationController applied_school.update_attribute(:status, 3) # 未审批删除 if params[:tip] == "unapplied" - AppliedMessage.create(:user_id => applied_school.user_id, :status => 3, :viewed => true, :applied_id => applied_school.id, :applied_type => "ApplyAddSchools", :name => applied_school.name ) - # 删除学校的用户 - users = UserExtensions.where("school_id = #{applied_school.school_id}") - users.each do |user| - user.update_column("school_id", nil) - end + AppliedMessage.create(:user_id => applied_school.user_id, :status => 3, :viewed => true, :applied_id => applied_school.id, :applied_type => "ApplyAddSchools", :name => applied_school.name ) + # 删除学校的用户 + users = UserExtensions.where("school_id = #{applied_school.school_id}") + users.update_all(:school_id => nil) applied_school.school.destroy redirect_to unapplied_schools_url # 已审批删除 elsif params[:tip] == "applied" - users = UserExtensions.where("school_id = #{applied_school.school_id}") - users.each do |user| - user.update_column("school_id", nil) - end applied_school.destroy redirect_to applied_schools_url end diff --git a/app/views/admin/_all_schools.html.erb b/app/views/admin/_all_schools.html.erb index d4cf916f5..ce5bc6dc7 100644 --- a/app/views/admin/_all_schools.html.erb +++ b/app/views/admin/_all_schools.html.erb @@ -8,7 +8,9 @@
      + <% if !@search.nil? %> <%= render :partial => "admin/update_school_form", :locals => {:schools => schools, :edit_id => edit_id} %> + <% end %>
      -
      -
      -
      -
        -
      • - 我的题库 -
      • -
      • - 题库 -
      • -
      • - 申请题库 -
      • -
      •  
      • -
      • - -
      • -
        +
        + +
        +
          +
        • + -
          -
          - <%=render :partial=>'homework_repository_search', :locals=>{:type => @type,:is_import => 0,:property => nil} %> -
          -
          -
          - <%=render :partial => 'homework_repository_list', :locals => {:homeworks => @homeworks,:type=>@type,:is_import => 0,:property => @property,:search=>''} %> -
          -
          - <%=render :partial => 'homework_repository_detail', :locals => {:homework => nil} %> -
          -
          -
          -
            - <%= pagination_links_full @hw_pages, @hw_count, :per_page_links => false, :remote => @is_remote, :flag => true%> -
          -
          -
          - 发送至 -
          - -
        -
        + +
      +
      +
      +
      +
      + <%=render :partial=>'homework_repository_search', :locals=>{:type => '1',:is_import => 0,:property => nil,:order => @order, :b_sort => @b_sort, :search => ''} %> +
      + +
      + <%=render :partial => 'homework_repository_list', :locals => {:homeworks => @homeworks,:type=>'1',:is_import => 0,:property => @property,:search=>''} %> +
      +
      +
      +
        + <%= pagination_links_full @hw_pages, @hw_count, :per_page_links => false, :remote => @is_remote, :flag => true%> +
      +
      \ No newline at end of file diff --git a/app/views/users/user_search_homeworks.js.erb b/app/views/users/user_search_homeworks.js.erb index 29d490960..4c8e640c3 100644 --- a/app/views/users/user_search_homeworks.js.erb +++ b/app/views/users/user_search_homeworks.js.erb @@ -5,5 +5,5 @@ $("#homework_detail_information").html("<%=escape_javascript(render :partial => <% else %> $("#homework_repository_list").html('<%= escape_javascript(render :partial => 'users/homework_repository_list', :locals => {:homeworks => @homeworks,:sort => @order,:b_sort => @b_sort,:type=>@type,:is_import => @is_import,:property => @property,:search=>@search})%>'); $("#homework_pository_ref_pages").html('<%= pagination_links_full @hw_pages, @hw_count, :per_page_links => false, :remote => @is_remote, :flag => true %>'); -$("#homework_repository_detail").html("<%=escape_javascript(render :partial => 'users/homework_repository_detail', :locals => {:homework=>nil}) %>"); +$("#homework_search_input").html('<%= escape_javascript(render :partial => 'users/homework_repository_search', :locals => {:type => @type,:is_import => @is_import,:property => @property,:order => @order, :b_sort => @b_sort, :search => @search})%>'); <% end %> \ No newline at end of file diff --git a/public/images/hw/icons_hw.png b/public/images/hw/icons_hw.png new file mode 100644 index 0000000000000000000000000000000000000000..013aa8afcbe1e11207742cdf8766b788249c8bf9 GIT binary patch literal 25185 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

      @x z0&!+W^%g`)`MrvPi|ML9{=Ta|I}&0MQl#Y2=*A%ZvX)Y5f9V%@`c|)oA9%8PZ)aYU zPpwb)$aq7TPyfN=`Mw43=F&c@*=h`2+y9hvb)A0o*hUWSfC5%Z;+*P0yltLc|d7acu1&+6rm$rfwg)qxk5VXV>VJ z&fd>a7TPTtxZ$CgZI}3@jmzFk)RcZH({Mv>i+4M#h(kwaIoj!MP`;=F;9VE-L+g!P z8+*NSje^TOz4KDLpzCxF;;HvZLWQ%^xRPL3(mq(R{Mr-3X`1`;_ht8(b6F5Cxxbiu zlw2BcVuQ5BF}BZqtB&@3(WjlPRT=(_y**Rm9KDG0{Roh>YkE=%Q81FZQx8PUDb9(H~j2&E7?{3HxIFs5P!{Szo)oG zo*OR?K87)S0^pI4Io1m`Tga|a8xvH`OB=ntr!y(>ag1pbMs zQ?gDbdnCtDTd@2E+Gcg5&+KLszPlUOoZu8Xt8SFCbR&mfRE;$MoxMIfnGs32myS<) zf8MJj(Bjw)MpOBE-@LSB(w(n_YeS}r@c+ Date: Wed, 3 Aug 2016 13:46:59 +0800 Subject: [PATCH 34/78] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E9=9B=86=E7=9A=84?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E3=80=81=E6=96=B0=E7=89=88=E5=88=86=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/users_controller.rb | 6 +-- app/views/layouts/_logined_header.html.erb | 6 --- .../_homework_repository_detail.html.erb | 19 +++++++++- app/views/users/user_homework_type.js.erb | 2 +- app/views/users/user_homeworks.html.erb | 32 +++++++++------- app/views/users/user_homeworks.js.erb | 3 +- app/views/users/user_search_homeworks.js.erb | 2 +- lib/redmine/pagination.rb | 37 ++++++++++++++++--- public/stylesheets/syllabus.css | 11 +++--- 9 files changed, 80 insertions(+), 38 deletions(-) diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 61f62480e..d610c701b 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -834,12 +834,12 @@ class UsersController < ApplicationController courses = @user.courses.where("is_delete = 1") course_ids = courses.empty? ? "(-1)" : "(" + courses.map{|course| course.id}.join(",") + ")" if @order == "course_name" - sql = "SELECT homework_commons.* FROM homework_commons INNER JOIN courses ON homework_commons.course_id = courses.id where homework_commons.course_id not in #{course_ids} and homework_commons.user_id = #{@user.id} and homework_type in #{type_ids} and publish_time <= '#{Date.today}' and (homework_commons.name like '%#{search}%') order by CONVERT (courses.name USING gbk) COLLATE gbk_chinese_ci #{@b_sort}" + sql = "SELECT homework_commons.* FROM homework_commons INNER JOIN courses ON homework_commons.course_id = courses.id where homework_commons.course_id not in #{course_ids} and homework_commons.user_id = #{@user.id} and homework_type in #{type_ids} and (homework_commons.name like '%#{search}%') order by CONVERT (courses.name USING gbk) COLLATE gbk_chinese_ci #{@b_sort}" @homeworks = HomeworkCommon.find_by_sql(sql) elsif @order == "user_name" - @homeworks = HomeworkCommon.where("user_id = #{@user.id} and course_id not in #{course_ids} and publish_time <= '#{Date.today}' and (name like '%#{search}%') and homework_type in #{type_ids}").joins(:user).order("CONVERT (lastname USING gbk) COLLATE gbk_chinese_ci #{@b_sort}, CONVERT (firstname USING gbk) COLLATE gbk_chinese_ci #{@b_sort},login #{@b_sort}") + @homeworks = HomeworkCommon.where("user_id = #{@user.id} and course_id not in #{course_ids} and (name like '%#{search}%') and homework_type in #{type_ids}").joins(:user).order("CONVERT (lastname USING gbk) COLLATE gbk_chinese_ci #{@b_sort}, CONVERT (firstname USING gbk) COLLATE gbk_chinese_ci #{@b_sort},login #{@b_sort}") else - @homeworks = HomeworkCommon.where("user_id = #{@user.id} and course_id not in #{course_ids} and publish_time <= '#{Date.today}' and (name like '%#{search}%') and homework_type in #{type_ids}").order("#{@order} #{@b_sort}") + @homeworks = HomeworkCommon.where("user_id = #{@user.id} and course_id not in #{course_ids} and (name like '%#{search}%') and homework_type in #{type_ids}").order("#{@order} #{@b_sort}") end elsif params[:type] == "2" #题库 visible_course = Course.where("is_public = 1 && is_delete = 0") diff --git a/app/views/layouts/_logined_header.html.erb b/app/views/layouts/_logined_header.html.erb index 7a47c8b66..b7e2989eb 100644 --- a/app/views/layouts/_logined_header.html.erb +++ b/app/views/layouts/_logined_header.html.erb @@ -10,15 +10,9 @@

      - <% if User.current.user_extensions && User.current.user_extensions.identity == 0 && User.current.allowed_to?(:add_course, nil, :global => true)%> - <% else %> - - <% end %> diff --git a/app/views/users/_homework_repository_detail.html.erb b/app/views/users/_homework_repository_detail.html.erb index 90f91c32d..f752fbfb3 100644 --- a/app/views/users/_homework_repository_detail.html.erb +++ b/app/views/users/_homework_repository_detail.html.erb @@ -14,7 +14,24 @@

      测试集:<%=@homework.homework_tests.count %>组

      - + <% if @homework.user == User.current && @homework.homework_tests.count > 0 %> + + + + + + + + <% @homework.homework_tests.each_with_index do |test, i| %> + + + + + + <% end %> + +
       测试集输入测试集输出
      <%=i+1 %><%=test.input %><%=test.output %>
      + <% end %> <% elsif @homework.homework_type ==3 && @homework.homework_detail_group %>

      分组人数:<%=@homework.homework_detail_group.min_num %> - <%=@homework.homework_detail_group.max_num %>人 diff --git a/app/views/users/user_homework_type.js.erb b/app/views/users/user_homework_type.js.erb index aa4c9ed57..95dee1c39 100644 --- a/app/views/users/user_homework_type.js.erb +++ b/app/views/users/user_homework_type.js.erb @@ -5,7 +5,7 @@ $("#homework_detail_information").html("<%=escape_javascript(render :partial => $("#homework_search_input").html("<%=escape_javascript(render :partial=>'homework_search_input', :locals=>{:type=>@type,:is_import=>@is_import}) %>"); <% else %> $("#homework_repository_list").html('<%= escape_javascript(render :partial => 'users/homework_repository_list', :locals => {:homeworks => @homeworks,:sort => @order,:b_sort => @b_sort,:type=>@type,:is_import => @is_import,:property => @property,:search=>''})%>'); -$("#homework_pository_ref_pages").html('<%= pagination_links_full @hw_pages, @hw_count, :per_page_links => false, :remote => @is_remote, :flag => true %>'); +$("#homework_pository_ref_pages").html('<%= pagination_links_full @hw_pages, @hw_count, :per_page_links => false, :remote => @is_remote, :flag => true, :is_new => true %>'); $("#homework_search_input").html('<%= escape_javascript(render :partial => 'users/homework_repository_search', :locals => {:type => @type,:is_import => @is_import,:property => @property,:order => @order, :b_sort => @b_sort, :search => ''})%>'); $("#homework_type_all").attr('href','<%= user_homework_type_user_path(@user,:type => @type,:is_import => 0,:property => 0) %>'); $("#homework_type_nor").attr('href','<%= user_homework_type_user_path(@user,:type => @type,:is_import => 0,:property => 1) %>'); diff --git a/app/views/users/user_homeworks.html.erb b/app/views/users/user_homeworks.html.erb index 7bbc1a82e..91c8beeae 100644 --- a/app/views/users/user_homeworks.html.erb +++ b/app/views/users/user_homeworks.html.erb @@ -25,7 +25,7 @@ } -

      +
      -
      - <%=render :partial=>'homework_repository_search', :locals=>{:type => '1',:is_import => 0,:property => nil,:order => @order, :b_sort => @b_sort, :search => ''} %> -
      + <% if @homeworks.empty? %> +
      +

      暂无可显示的内容~

      + <% else %> +
      + <%=render :partial=>'homework_repository_search', :locals=>{:type => '1',:is_import => 0,:property => nil,:order => @order, :b_sort => @b_sort, :search => ''} %> +
      -
      - <%=render :partial => 'homework_repository_list', :locals => {:homeworks => @homeworks,:type=>'1',:is_import => 0,:property => @property,:search=>''} %> -
      -
      -
      -
        - <%= pagination_links_full @hw_pages, @hw_count, :per_page_links => false, :remote => @is_remote, :flag => true%> -
      -
      +
      + <%=render :partial => 'homework_repository_list', :locals => {:homeworks => @homeworks,:type=>'1',:is_import => 0,:property => @property,:search=>''} %> +
      + +
      +
        + <%= pagination_links_full @hw_pages, @hw_count, :per_page_links => false, :remote => @is_remote, :flag => true, :is_new => true%> +
      +
      +
      + <% end %>
      \ No newline at end of file diff --git a/app/views/users/user_homeworks.js.erb b/app/views/users/user_homeworks.js.erb index ce1bb65e2..ac5b4e3d6 100644 --- a/app/views/users/user_homeworks.js.erb +++ b/app/views/users/user_homeworks.js.erb @@ -1,4 +1,3 @@ /*$("#homework_repository").html('<%#= escape_javascript(render :partial => 'users/homework_repository', :locals => {:homeworks => @homeworks})%>');*/ $("#homework_repository_list").html('<%= escape_javascript(render :partial => 'users/homework_repository_list', :locals => {:homeworks => @homeworks,:sort => @order,:b_sort => @b_sort,:type=>@type,:is_import => 0,:property => @property,:search=>''})%>'); -$("#homework_pository_ref_pages").html('<%= pagination_links_full @hw_pages, @hw_count, :per_page_links => false, :remote => @is_remote, :flag => true %>'); -$("#homework_repository_detail").html("<%=escape_javascript(render :partial => 'users/homework_repository_detail', :locals => {:homework=>nil}) %>"); +$("#homework_pository_ref_pages").html('<%= pagination_links_full @hw_pages, @hw_count, :per_page_links => false, :remote => @is_remote, :flag => true, :is_new => true %>'); \ No newline at end of file diff --git a/app/views/users/user_search_homeworks.js.erb b/app/views/users/user_search_homeworks.js.erb index 4c8e640c3..d344d8cd7 100644 --- a/app/views/users/user_search_homeworks.js.erb +++ b/app/views/users/user_search_homeworks.js.erb @@ -4,6 +4,6 @@ $("#homewrok_ref_pages").html('<%= pagination_links_full @hw_pages, @hw_count, : $("#homework_detail_information").html("<%=escape_javascript(render :partial => 'users/homework_detail_information', :locals => {:homework=>nil}) %>"); <% else %> $("#homework_repository_list").html('<%= escape_javascript(render :partial => 'users/homework_repository_list', :locals => {:homeworks => @homeworks,:sort => @order,:b_sort => @b_sort,:type=>@type,:is_import => @is_import,:property => @property,:search=>@search})%>'); -$("#homework_pository_ref_pages").html('<%= pagination_links_full @hw_pages, @hw_count, :per_page_links => false, :remote => @is_remote, :flag => true %>'); +$("#homework_pository_ref_pages").html('<%= pagination_links_full @hw_pages, @hw_count, :per_page_links => false, :remote => @is_remote, :flag => true, :is_new => true %>'); $("#homework_search_input").html('<%= escape_javascript(render :partial => 'users/homework_repository_search', :locals => {:type => @type,:is_import => @is_import,:property => @property,:order => @order, :b_sort => @b_sort, :search => @search})%>'); <% end %> \ No newline at end of file diff --git a/lib/redmine/pagination.rb b/lib/redmine/pagination.rb index 9132f973c..9b751869b 100644 --- a/lib/redmine/pagination.rb +++ b/lib/redmine/pagination.rb @@ -231,6 +231,7 @@ module Redmine per_page_links = options[:per_page_links] remote = options[:remote] ? options[:remote] : false flag = options[:flag] ? options[:flag] : false + is_new = options[:is_new] ? options[:is_new] : false per_page_links = false if count.nil? page_param = paginator.page_param @@ -242,7 +243,11 @@ module Redmine else text = "\xc2\xab " + l(:label_previous) end - html << '
    • ' << yield(text, {page_param => paginator.previous_page}, :class => 'previous c_blue', :remote => remote) << '
    • ' + ' ' + if is_new + html << '
    • ' << yield(text, {page_param => paginator.previous_page}, :class => 'pages-big', :remote => remote) << '
    • ' + ' ' + else + html << '
    • ' << yield(text, {page_param => paginator.previous_page}, :class => 'previous c_blue', :remote => remote) << '
    • ' + ' ' + end end unless paginator.previous_page if paginator.next_page @@ -251,7 +256,11 @@ module Redmine else text = "\xc2\xab " + l(:label_previous) end - html << '
    • ' << yield(text, {page_param => paginator.previous_page}, :class => 'previous c_blue', :remote => remote) << '
    • ' + ' ' + if is_new + html << '
    • ' << yield(text, {page_param => paginator.previous_page}, :class => 'pages-big', :remote => remote) << '
    • ' + ' ' + else + html << '
    • ' << yield(text, {page_param => paginator.previous_page}, :class => 'previous c_blue', :remote => remote) << '
    • ' + ' ' + end end end @@ -259,14 +268,22 @@ module Redmine paginator.linked_pages.each do |page| if previous && previous != page - 1 if flag - html << '
    • ' << content_tag('a', '...', :class => 'c_blue') << '
    • ' + ' ' + if is_new + html << '
    • ' << content_tag('a', '...', :class => 'c_blue') << '
    • ' + ' ' + else + html << '
    • ' << content_tag('a', '...') << '
    • ' + ' ' + end else html << '
    • ' << content_tag('span', '...', :class => 'spacer ') << '
    • ' + ' ' end end if page == paginator.page if flag - html << '
    • ' << content_tag('a', page.to_s, :class => 'current-page c_white') << '
    • ' + if is_new + html << '
    • ' << content_tag('a', page.to_s, :class => 'active') << '
    • ' + else + html << '
    • ' << content_tag('a', page.to_s, :class => 'current-page c_white') << '
    • ' + end else html << '
    • ' << content_tag('span', page.to_s, :class => 'current-page') << '
    • ' end @@ -283,7 +300,11 @@ module Redmine else text = l(:label_next) + " \xc2\xbb" end - html << '
    • ' << yield(text, {page_param => paginator.next_page}, :class => 'next c_blue', :remote => remote) << '
    • ' + ' ' + if is_new + html << '
    • ' << yield(text, {page_param => paginator.next_page}, :class => 'pages-big', :remote => remote) << '
    • ' + ' ' + else + html << '
    • ' << yield(text, {page_param => paginator.next_page}, :class => 'next c_blue', :remote => remote) << '
    • ' + ' ' + end end unless paginator.next_page @@ -293,7 +314,11 @@ module Redmine else text = l(:label_next) + " \xc2\xbb" end - html << "
    • " << yield(text, {page_param => paginator.next_page}, :class => 'next c_blue', :remote => remote) << "
    • " + ' ' + if is_new + html << '
    • ' << yield(text, {page_param => paginator.next_page}, :class => 'pages-big', :remote => remote) << '
    • ' + ' ' + else + html << '
    • ' << yield(text, {page_param => paginator.next_page}, :class => 'next c_blue', :remote => remote) << '
    • ' + ' ' + end end end diff --git a/public/stylesheets/syllabus.css b/public/stylesheets/syllabus.css index 09eb78be3..768e8dce5 100644 --- a/public/stylesheets/syllabus.css +++ b/public/stylesheets/syllabus.css @@ -607,11 +607,12 @@ a:hover.sy_class_ltitle{ color:#333;} .hw_files_icon{display:block; width:17px; height:14px; background:url(../images/hw/icons_hw.png) 0 -135px no-repeat;} .hw_list_classname{ width:300px; overflow:hidden; display:block;overflow:hidden;white-space: nowrap; text-overflow:ellipsis;} .hw_list_teachername{ width:80px; overflow:hidden; display:block;overflow:hidden;white-space: nowrap; text-overflow:ellipsis;} +/* 测试集显示 */ +.hw_popup_testtable{background:#fff; color:#888888; margin:10px 0; border-right:1px solid #e7e7e7; border-bottom:1px solid #e7e7e7;} +.hw_popup_testtable tr td{ width:47%; padding:10px; color:#888; border-left:1px solid #e7e7e7; border-top:1px solid #e7e7e7; } +.hw_popup_testtable tr td.test_td_min{ width:5%; color:#888;} +.hw_popup_testtable tr td.test_td_title{ text-align:center; color:#888888;} /* 我的作业 */ .hw_classname{ width:180px; overflow:hidden; display:block;overflow:hidden;white-space: nowrap; text-overflow:ellipsis;} -#hw_tab_con_1 .sy_classbox .sy_classlist:last-child{ border-bottom:1px solid #ddd;} -.hw_tab_top{ height: 50px; line-height: 50px; padding-left: 15px; border-bottom:1px solid #ddd; border-left:3px solid #3b94d6; } - - - +.hw_tab_top{ height: 50px; line-height: 50px; padding-left: 15px; border-bottom:1px solid #ddd; border-left:3px solid #3b94d6; } \ No newline at end of file From bae775ec34c57e02f1805e7c96d1d02a2f7e93dc Mon Sep 17 00:00:00 2001 From: cxt Date: Wed, 3 Aug 2016 14:06:47 +0800 Subject: [PATCH 35/78] =?UTF-8?q?=E9=A2=98=E5=BA=93=E7=9A=84=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../users/_homework_repository_list.html.erb | 7 ++++- .../_homework_repository_search.html.erb | 16 ++-------- .../users/_homework_repository_sort.html.erb | 13 +++++++++ app/views/users/user_homeworks.html.erb | 29 ++++++++----------- app/views/users/user_search_homeworks.js.erb | 2 +- 5 files changed, 35 insertions(+), 32 deletions(-) create mode 100644 app/views/users/_homework_repository_sort.html.erb diff --git a/app/views/users/_homework_repository_list.html.erb b/app/views/users/_homework_repository_list.html.erb index 24fd0a52c..aa45f2115 100644 --- a/app/views/users/_homework_repository_list.html.erb +++ b/app/views/users/_homework_repository_list.html.erb @@ -1,4 +1,8 @@ -<% homeworks.each do |homework| %> +<% if homeworks.empty? %> +
      +

      暂无可显示的内容~

      +<% else %> + <% homeworks.each do |homework| %> +<% end %> <% end %> \ No newline at end of file diff --git a/app/views/users/_homework_repository_search.html.erb b/app/views/users/_homework_repository_search.html.erb index 4bd6f49d0..26f598a8e 100644 --- a/app/views/users/_homework_repository_search.html.erb +++ b/app/views/users/_homework_repository_search.html.erb @@ -1,16 +1,6 @@ -排序: -<%= link_to "发布时间",user_search_homeworks_user_path(@user,:name=>search,:type => type,:is_import=>is_import,:property=>property,:order => "publish_time", :sort => @r_sort),:class => "sy_cgrey fl",:remote => true%> -<% if order == "publish_time" %> - <%= link_to "", user_search_homeworks_user_path(@user,:name=>search,:type => type,:is_import=>is_import,:property=>property,:order => "publish_time", :sort => @r_sort), :class => "#{@r_sort == 'asc' ? 'sortupbtn' : 'sortdownbtn'} mt15 fl", :remote => true %> -<% else %> - <%= link_to "", user_search_homeworks_user_path(@user,:name=>search,:type => type,:is_import=>is_import,:property=>property,:order => "publish_time", :sort => @r_sort), :class => "sortdownbtn sort_no mt15 fl", :remote => true %> -<% end %> -<%= link_to "引用数",user_search_homeworks_user_path(@user,:name=>search,:type => type,:is_import=>is_import,:property=>property,:order => "quotes", :sort => @r_sort),:class => "sy_cgrey fl",:remote => true%> -<% if order == "quotes" %> - <%= link_to "", user_search_homeworks_user_path(@user,:name=>search,:type => type,:is_import=>is_import,:property=>property,:order => "quotes", :sort => @r_sort), :class => "#{@r_sort == 'asc' ? 'sortupbtn' : 'sortdownbtn'} mt15 fl", :remote => true %> -<% else %> - <%= link_to "", user_search_homeworks_user_path(@user,:name=>search,:type => type,:is_import=>is_import,:property=>property,:order => "quotes", :sort => @r_sort), :class => "sortdownbtn sort_no mt15 fl", :remote => true %> -<% end %> +
      + <%= render :partial => 'users/homework_repository_sort', :locals => {:type => type,:is_import => is_import,:property => property,:order => @order,:search => search} %> +
      - <% if @homeworks.empty? %> -
      -

      暂无可显示的内容~

      - <% else %> -
      - <%=render :partial=>'homework_repository_search', :locals=>{:type => '1',:is_import => 0,:property => nil,:order => @order, :b_sort => @b_sort, :search => ''} %> -
      +
      + <%=render :partial=>'homework_repository_search', :locals=>{:type => '1',:is_import => 0,:property => nil,:order => @order, :search => ''} %> +
      -
      - <%=render :partial => 'homework_repository_list', :locals => {:homeworks => @homeworks,:type=>'1',:is_import => 0,:property => @property,:search=>''} %> -
      +
      + <%=render :partial => 'homework_repository_list', :locals => {:homeworks => @homeworks,:type=>'1',:is_import => 0,:property => @property,:search=>''} %> +
      -
      -
        - <%= pagination_links_full @hw_pages, @hw_count, :per_page_links => false, :remote => @is_remote, :flag => true, :is_new => true%> -
      -
      -
      - <% end %> +
      +
        + <%= pagination_links_full @hw_pages, @hw_count, :per_page_links => false, :remote => @is_remote, :flag => true, :is_new => true%> +
      +
      +
      \ No newline at end of file diff --git a/app/views/users/user_search_homeworks.js.erb b/app/views/users/user_search_homeworks.js.erb index d344d8cd7..fbf73f6e2 100644 --- a/app/views/users/user_search_homeworks.js.erb +++ b/app/views/users/user_search_homeworks.js.erb @@ -5,5 +5,5 @@ $("#homework_detail_information").html("<%=escape_javascript(render :partial => <% else %> $("#homework_repository_list").html('<%= escape_javascript(render :partial => 'users/homework_repository_list', :locals => {:homeworks => @homeworks,:sort => @order,:b_sort => @b_sort,:type=>@type,:is_import => @is_import,:property => @property,:search=>@search})%>'); $("#homework_pository_ref_pages").html('<%= pagination_links_full @hw_pages, @hw_count, :per_page_links => false, :remote => @is_remote, :flag => true, :is_new => true %>'); -$("#homework_search_input").html('<%= escape_javascript(render :partial => 'users/homework_repository_search', :locals => {:type => @type,:is_import => @is_import,:property => @property,:order => @order, :b_sort => @b_sort, :search => @search})%>'); +$("#homework_repository_sort").html('<%= escape_javascript(render :partial => 'users/homework_repository_sort', :locals => {:type => @type,:is_import => @is_import,:property => @property,:order => @order, :search => @search})%>'); <% end %> \ No newline at end of file From a34272027e4d405c279c773ee2ca7b703df29416 Mon Sep 17 00:00:00 2001 From: yuanke <249218296@qq.com> Date: Wed, 3 Aug 2016 14:55:54 +0800 Subject: [PATCH 36/78] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E8=8F=9C=E5=8D=95?= =?UTF-8?q?=E5=8F=8A=E9=A1=B9=E7=9B=AE=E7=8F=AD=E7=BA=A7=E5=AE=A1=E6=A0=B8?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/mobile/apis/projects.rb | 6 +-- app/api/mobile/entities/project.rb | 2 +- app/models/applied_project.rb | 1 + app/services/projects_service.rb | 14 +++--- config/menu.yml.production | 8 +-- config/menu.yml.test | 8 +-- .../assets/wechat/review_project_member.html | 8 +-- .../wechat/controllers/class_list.js | 49 +++++++++++++------ .../wechat/controllers/homework.js | 2 +- .../javascripts/wechat/controllers/project.js | 25 ++++++++-- .../wechat/controllers/project_list.js | 4 ++ .../wechat/controllers/review_class_member.js | 2 +- .../controllers/review_project_member.js | 12 +++-- 13 files changed, 95 insertions(+), 46 deletions(-) diff --git a/app/api/mobile/apis/projects.rb b/app/api/mobile/apis/projects.rb index 04863c6e5..8f6e7d96d 100644 --- a/app/api/mobile/apis/projects.rb +++ b/app/api/mobile/apis/projects.rb @@ -102,8 +102,8 @@ module Mobile present :master_members,master_members, with: Mobile::Entities::ProjectMember present :develop_members,develop_members, with: Mobile::Entities::ProjectMember present :report_members,report_members, with: Mobile::Entities::ProjectMember - present :report_members,review_master_members - present :report_members,review_develop_members + present :review_master_members,review_master_members + present :review_develop_members,review_develop_members present :status, 0 end @@ -207,7 +207,7 @@ module Mobile authenticate! ps = ProjectsService.new - reviewer = ps.get_reviewer_info(params) + reviewer = ps.get_reviewer_info params present :data, reviewer, with: Mobile::Entities::User present :status, 0 end diff --git a/app/api/mobile/entities/project.rb b/app/api/mobile/entities/project.rb index 55ab67be2..073f7cd0f 100644 --- a/app/api/mobile/entities/project.rb +++ b/app/api/mobile/entities/project.rb @@ -5,7 +5,7 @@ module Mobile expose :id expose :user_id expose :invite_code - # expose :qrcode + expose :qrcode expose :can_setting, if: lambda { |instance, options| options[:user] } do |instance, options| current_user = options[:user] diff --git a/app/models/applied_project.rb b/app/models/applied_project.rb index 7597778f8..abab2ab6f 100644 --- a/app/models/applied_project.rb +++ b/app/models/applied_project.rb @@ -1,3 +1,4 @@ +#coding=utf-8 class AppliedProject < ActiveRecord::Base attr_accessible :project_id, :user_id, :role diff --git a/app/services/projects_service.rb b/app/services/projects_service.rb index a98c76839..7358bc15c 100644 --- a/app/services/projects_service.rb +++ b/app/services/projects_service.rb @@ -3,6 +3,9 @@ class ProjectsService include ApplicationHelper + include ApiHelper + include ActionView::Helpers::DateHelper + include ProjectsHelper #获取指定用户的项目列表 def user_projects(user) @@ -14,7 +17,7 @@ class ProjectsService def show_project(params,current_user) project = Project.find(params[:id]) project.generate_invite_code - # project.generate_qrcode + project.generate_qrcode project end @@ -187,7 +190,7 @@ class ProjectsService role_name: "", name: user.show_name, roles_id: role_id, - :brief_introduction => user.user_extensions.brief_introduction,:realname=>user.realname} + :brief_introduction => user.user_extensions.brief_introduction,:realname=>user.realname,:real_name=>user.realname} end end end @@ -199,8 +202,7 @@ class ProjectsService info = nil project = Project.find(params[:project_id]) if project - messages = AppliedProject.where("project_id = ? and user_id=?",project.id,params[:user_id]).first - + messages = AppliedProject.where(:project_id=> project.id, :user_id=>params[:user_id]).first if messages user = User.find(params[:user_id]) if user @@ -212,7 +214,7 @@ class ProjectsService :work_unit => work_unit, :mail => user.mail, :location => location, role_name: "", name: user.show_name, - roles_id: messages.role_id, + roles_id: messages.role, :brief_introduction => user.user_extensions.brief_introduction,:realname=>user.realname} end end @@ -238,7 +240,7 @@ class ProjectsService applied_project = apply_message.applied ap_role = applied_project.try(:role) if ap_role - rolename = ap_role == 3 ? :"管理人员" : "开发人员" + rolename = ap_role == 3 ? "管理人员" : "开发人员" if params[:type] == 0 #同意 members = [] diff --git a/config/menu.yml.production b/config/menu.yml.production index f97c27d7d..c1431172e 100644 --- a/config/menu.yml.production +++ b/config/menu.yml.production @@ -23,13 +23,13 @@ button: name: "更多" sub_button: - - type: "click" + type: "view" name: "加入班级" - key: "JOIN_CLASS" + url: "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx8e1ab05163a28e37&redirect_uri=https://www.trustie.net/wechat/user_activities&response_type=code&scope=snsapi_base&state=join_class#wechat_redirect" - - type: "click" + type: "view" name: "加入项目" - key: "JOIN_PROJECT" + url: "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx8e1ab05163a28e37&redirect_uri=https://www.trustie.net/wechat/user_activities&response_type=code&scope=snsapi_base&state=join_project#wechat_redirect" - type: "view" name: "历史推文" diff --git a/config/menu.yml.test b/config/menu.yml.test index bdc47ba8d..dc4aacbe5 100644 --- a/config/menu.yml.test +++ b/config/menu.yml.test @@ -23,13 +23,13 @@ button: name: "更多" sub_button: - - type: "click" + type: "view" name: "加入班级" - key: "JOIN_CLASS" + url: "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxc09454f171153c2d&redirect_uri=https://test.forge.trustie.net/wechat/user_activities&response_type=code&scope=snsapi_base&state=join_class#wechat_redirect" - - type: "click" + type: "view" name: "加入项目" - key: "JOIN_PROJECT" + url: "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxc09454f171153c2d&redirect_uri=https://test.forge.trustie.net/wechat/user_activities&response_type=code&scope=snsapi_base&state=join_project#wechat_redirect" - type: "view" name: "历史推文" diff --git a/public/assets/wechat/review_project_member.html b/public/assets/wechat/review_project_member.html index a78eace83..b03fdd276 100644 --- a/public/assets/wechat/review_project_member.html +++ b/public/assets/wechat/review_project_member.html @@ -1,12 +1,12 @@
      -
      +
      {{project.name}}
      -
      项目邀请码
      +
      {{current_review_member.realname == "" ? current_review_member.name : current_review_member.realname}}
      角色
        -
      • -
      • +
      • +
      拒绝 diff --git a/public/javascripts/wechat/controllers/class_list.js b/public/javascripts/wechat/controllers/class_list.js index d27383a3b..98910242f 100644 --- a/public/javascripts/wechat/controllers/class_list.js +++ b/public/javascripts/wechat/controllers/class_list.js @@ -16,6 +16,27 @@ app.controller('ClassListController', ['$scope', 'config', 'auth', '$http', '$lo function (response) { console.log(response.data); vm.syllabuses = response.data.data; + + var show_1 = false; + var show_2 = false; + + for (var i in vm.syllabuses) { + if(vm.syllabuses[i].can_setting && vm.syllabuses[i].courses.length > 0 && show_1 == false ){ + vm.syllabuses[i].show_plus = true; + show_1 = true; + } + + if(!vm.syllabuses[i].can_setting && vm.syllabuses[i].courses.length > 0 && show_2 == false ){ + vm.syllabuses[i].show_plus = true; + show_2 = true; + } + + if(show_1 && show_2){ + break; + } + + } + rms.save('syllabuses', vm.syllabuses); } ); @@ -25,7 +46,6 @@ app.controller('ClassListController', ['$scope', 'config', 'auth', '$http', '$lo loadClassList(); } - vm.goClass = function (course_id) { console.log(course_id); $location.path("/class").search({id: course_id}); @@ -33,22 +53,23 @@ app.controller('ClassListController', ['$scope', 'config', 'auth', '$http', '$lo vm.newClass = function () { //先判断下权限 - $http.post(config.apiUrl + "syllabuses/auth",{token: auth.token()} ).then( - function (response) { - console.log(response.data); - if (response.data.auth == 0) { - vm.alertService_1.showMessage('提示', '非教师身份不能创建课程哦~'); - } - else{ - $location.path("/new_class"); - } - } - ); - } +// $http.post(config.apiUrl + "syllabuses/auth",{token: auth.token()} ).then( +// function (response) { +// console.log(response.data); +// if (response.data.auth == 0) { +// vm.alertService_1.showMessage('提示', '非教师身份不能创建课程哦~'); +// } +// else{ +// $location.path("/new_class"); +// } +// } +// ); + $location.path("/new_class"); + }; vm.goResource = function () { $location.path("/myresource"); - } + }; vm.joinClass = function () { // vm.alertService_3.showMessage('提示', '请输入5位班级邀请码(不区分大小写)', function(){ diff --git a/public/javascripts/wechat/controllers/homework.js b/public/javascripts/wechat/controllers/homework.js index 2898fc27f..d1547a091 100644 --- a/public/javascripts/wechat/controllers/homework.js +++ b/public/javascripts/wechat/controllers/homework.js @@ -12,7 +12,7 @@ app.controller('HomeworkController', ['$scope', '$http', '$routeParams', 'auth', replytype = data.type; page = data.page; - if (replytype == 0){ + if (replytype == 0){f if (page == 0){ $scope.homework = data.data; $scope.page = 0; diff --git a/public/javascripts/wechat/controllers/project.js b/public/javascripts/wechat/controllers/project.js index eded4ecc7..206730486 100644 --- a/public/javascripts/wechat/controllers/project.js +++ b/public/javascripts/wechat/controllers/project.js @@ -22,8 +22,8 @@ app.controller('ProjectController', ['$scope', 'config','$http','$timeout', 'aut // vm.review_master_members = rms.get("review_master_members") || []; // vm.review_develop_members = rms.get("review_master_members") || []; - vm.review_master_members = []; - vm.review_develop_members = []; + vm.review_master_members = rms.get("review_master_members") || []; + vm.review_develop_members = rms.get("review_develop_members") || []; // vm.project_members_has_more = rms.get("project_members_has_more"); @@ -33,6 +33,15 @@ app.controller('ProjectController', ['$scope', 'config','$http','$timeout', 'aut vm.invite = function(){ // vm.alertService.showMessage('提示', "该功能将在近日开放,敬请期待!"); + rms.save('project_activities_page',vm.project_activities_page); + rms.save("project_activities",vm.project_activities); + rms.save("project_has_more",vm.project_has_more); + rms.save("project",vm.project); + rms.save("project_master_members",vm.project_master_members); + rms.save("project_develop_members",vm.project_develop_members); + rms.save("project_report_members",vm.project_report_members); + rms.save("review_master_members",vm.review_master_members); + rms.save("review_develop_members",vm.review_develop_members); $location.path("/project_invite_code").search({id: projectid}); }; @@ -149,9 +158,11 @@ app.controller('ProjectController', ['$scope', 'config','$http','$timeout', 'aut if(tag){ vm.tab(2); tag = null; + vm.currentTab = 2; } else{ vm.tab(1); + vm.currentTab = 1; } } else{ @@ -162,8 +173,6 @@ app.controller('ProjectController', ['$scope', 'config','$http','$timeout', 'aut } } ); - vm.currentTab = 1; - vm.tab(vm.currentTab); } else { $timeout(function(){ window.scrollTo(0, rms.get("yoffset")); @@ -205,6 +214,8 @@ app.controller('ProjectController', ['$scope', 'config','$http','$timeout', 'aut rms.save("project_master_members",vm.project_master_members); rms.save("project_develop_members",vm.project_develop_members); rms.save("project_report_members",vm.project_report_members); + rms.save("review_master_members",vm.review_master_members); + rms.save("review_develop_members",vm.review_develop_members); $location.path("/edit_project_member").search({id: projectid,user_id: data.user.id}); }; @@ -212,6 +223,12 @@ app.controller('ProjectController', ['$scope', 'config','$http','$timeout', 'aut vm.review = function(user){ rms.save('current_review_member', user); rms.save('current_project', vm.project); + rms.save("project",vm.project); + rms.save("project_master_members",vm.project_master_members); + rms.save("project_develop_members",vm.project_develop_members); + rms.save("project_report_members",vm.project_report_members); + rms.save("review_master_members",vm.review_master_members); + rms.save("review_develop_members",vm.review_develop_members); $location.path("/review_project_member").search({id: projectid,user_id: user.id}); } diff --git a/public/javascripts/wechat/controllers/project_list.js b/public/javascripts/wechat/controllers/project_list.js index 0be66cd62..7471ca803 100644 --- a/public/javascripts/wechat/controllers/project_list.js +++ b/public/javascripts/wechat/controllers/project_list.js @@ -17,6 +17,10 @@ app.controller('ProjectListController', ['$scope', 'config', 'auth', '$http', '$ function (response) { console.log(response.data); vm.projects = response.data.data; + + + + rms.save('projects', vm.projects); } ); diff --git a/public/javascripts/wechat/controllers/review_class_member.js b/public/javascripts/wechat/controllers/review_class_member.js index 68f715447..6e8cb16eb 100644 --- a/public/javascripts/wechat/controllers/review_class_member.js +++ b/public/javascripts/wechat/controllers/review_class_member.js @@ -57,7 +57,7 @@ app.controller('ReviewClassMemberController', ['$scope', '$http', 'auth', 'confi }).then(function(response) { if (response.data.status == 0) { vm.alertService.showMessage('提示', response.data.message, function () { - $location.path("/class_list"); + $location.path("/class").search({id: course_id,tag:1}); }); } else{ diff --git a/public/javascripts/wechat/controllers/review_project_member.js b/public/javascripts/wechat/controllers/review_project_member.js index f5b554832..113aa426b 100644 --- a/public/javascripts/wechat/controllers/review_project_member.js +++ b/public/javascripts/wechat/controllers/review_project_member.js @@ -13,7 +13,7 @@ app.controller('ReviewProjectMemberController', ['$scope', '$http', 'auth', 'con var project_id = $routeParams.id; var user_id = $routeParams.user_id; - if(!vm.current_course){ + if(!vm.current_project){ $http.get(config.apiUrl+ 'projects/'+project_id+"?token="+auth.token()).then( function(response) { console.log(response.data); @@ -44,8 +44,6 @@ app.controller('ReviewProjectMemberController', ['$scope', '$http', 'auth', 'con console.log(response.data.data); } }); - - } vm.deal = function(result){ @@ -57,7 +55,13 @@ app.controller('ReviewProjectMemberController', ['$scope', '$http', 'auth', 'con }).then(function(response) { if (response.data.status == 0) { vm.alertService.showMessage('提示', response.data.message, function () { - $location.path("/project_list"); + rms.save("project_master_members",[]); + rms.save("project_develop_members",[]); + rms.save("project_report_members",[]); + rms.save("review_master_members",[]); + rms.save("review_develop_members",[]); + rms.save("tab_num",null); + $location.path("/project").search({id: project_id,tag:1}); }); } else{ From a5fe620452739f972e5de42eec8f4b05c4d358e6 Mon Sep 17 00:00:00 2001 From: Tim Date: Wed, 3 Aug 2016 14:57:02 +0800 Subject: [PATCH 37/78] =?UTF-8?q?=E9=A2=98=E5=BA=93=E7=BF=BB=E9=A1=B5?= =?UTF-8?q?=E5=B1=85=E4=B8=AD=E5=AF=B9=E9=BD=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/users/user_homeworks.html.erb | 12 ++++++++---- public/stylesheets/css/public.css | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/app/views/users/user_homeworks.html.erb b/app/views/users/user_homeworks.html.erb index 91c8beeae..d2fd17028 100644 --- a/app/views/users/user_homeworks.html.erb +++ b/app/views/users/user_homeworks.html.erb @@ -60,11 +60,15 @@ <%=render :partial => 'homework_repository_list', :locals => {:homeworks => @homeworks,:type=>'1',:is_import => 0,:property => @property,:search=>''} %>
      -
      -
        - <%= pagination_links_full @hw_pages, @hw_count, :per_page_links => false, :remote => @is_remote, :flag => true, :is_new => true%> -
      +
      +
      +
        + <%= pagination_links_full @hw_pages, @hw_count, :per_page_links => false, :remote => @is_remote, :flag => true, :is_new => true%> +
      +
      +
      +
      <% end %>
      diff --git a/public/stylesheets/css/public.css b/public/stylesheets/css/public.css index cc27955d5..26c43756d 100644 --- a/public/stylesheets/css/public.css +++ b/public/stylesheets/css/public.css @@ -527,6 +527,7 @@ a.list-title{ font-size:14px; font-weight: bold; color:#000; white-space:nowrap; a.pages-big{ width:50px;} .pages .active{ background-color:#3b94d6; border:1px solid #3b94d6; color:#fff;} .pages{width:330px; margin:20px auto 10px;} +.pages li {display:inline-block;} /*课程列表界面样式*/ a.course-title{ font-size:14px; font-weight: bold; color:#000;white-space:nowrap; overflow:hidden; text-overflow:ellipsis; display:block; width:590px;} From cecf917764d9f1492f4d968bd3bd681f36cf6e52 Mon Sep 17 00:00:00 2001 From: cxt Date: Wed, 3 Aug 2016 15:00:16 +0800 Subject: [PATCH 38/78] =?UTF-8?q?=E4=BB=8E=E9=A2=98=E5=BA=93=E9=80=89?= =?UTF-8?q?=E7=94=A8=E4=BD=9C=E4=B8=9A=E6=97=B6=E5=A2=9E=E5=8A=A0=E6=8F=90?= =?UTF-8?q?=E7=A4=BA=EF=BC=9A=E2=80=9C=E6=82=A8=E9=80=89=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=E9=A2=98=E6=98=AF=E2=80=9C=E6=88=91=E6=94=B6=E5=88=B0=E7=9A=84?= =?UTF-8?q?=E4=BD=9C=E4=B8=9A=E2=80=9D=EF=BC=8C=E4=B8=8D=E8=83=BD=E9=80=89?= =?UTF-8?q?=E7=94=A8=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/users_controller.rb | 15 +++++++++++- app/views/users/_show_user_homeworks.html.erb | 23 ++++++++++++++++++- app/views/users/show_homework_detail.js.erb | 1 + app/views/users/user_homework_type.js.erb | 1 + app/views/users/user_search_homeworks.js.erb | 1 + config/routes.rb | 1 + 6 files changed, 40 insertions(+), 2 deletions(-) diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index d610c701b..9887fd1ab 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -739,7 +739,7 @@ class UsersController < ApplicationController #@user_homeworks = HomeworkCommon.where(:user_id => @user.id).order("created_at desc") courses = @user.courses.where("is_delete = 1") course_ids = courses.empty? ? "(-1)" : "(" + courses.map{|course| course.id}.join(",") + ")" - @homeworks = HomeworkCommon.where("user_id = #{@user.id} and publish_time <= '#{Date.today}' and course_id not in #{course_ids}").order("#{@order} #{@b_sort}") + @homeworks = HomeworkCommon.where("user_id = #{@user.id} and course_id not in #{course_ids}").order("#{@order} #{@b_sort}") @type = params[:type] @limit = 15 @is_remote = true @@ -894,6 +894,19 @@ class UsersController < ApplicationController end end + #检查改作业是否可以选用 + def check_homework + homework = HomeworkCommon.find_by_id params[:homework] + student_ids = homework.course.student.empty? ? [] : homework.course.student.map{|student| student.student_id}.join(',') + resultObj = {status: 2} + if student_ids.include?(User.current.id.to_s) + resultObj[:status] = 1 + else + resultObj[:status] = 0 + end + render :json => resultObj + end + #导入作业,确定按钮 def user_select_homework homework = HomeworkCommon.find_by_id params[:checkMenu] diff --git a/app/views/users/_show_user_homeworks.html.erb b/app/views/users/_show_user_homeworks.html.erb index f54f49865..53b15c0d2 100644 --- a/app/views/users/_show_user_homeworks.html.erb +++ b/app/views/users/_show_user_homeworks.html.erb @@ -25,8 +25,9 @@ <%= render :partial => 'users/show_user_homework_form', :locals => {:homeworks => @homeworks}%>
      <% end %> +
      取消 @@ -44,6 +45,26 @@
      diff --git a/app/views/users/user_courses4show.js.erb b/app/views/users/user_courses4show.js.erb index fddbcf032..3a99dc484 100644 --- a/app/views/users/user_courses4show.js.erb +++ b/app/views/users/user_courses4show.js.erb @@ -1 +1 @@ -$("#user_show_more_course").replaceWith("<%= escape_javascript( render :partial => 'layouts/user_courses',:locals => {:courses => @courses,:user => @user,:type=>@type,:page => @page, :all_count => @all_count} )%>"); +$("#user_show_more_course").replaceWith("<%= escape_javascript( render :partial => 'layouts/user_courses',:locals => {:courses => @courses,:user => @user,:page => @page, :all_count => @all_count} )%>"); diff --git a/public/images/user/female.jpg b/public/images/user/female.jpg new file mode 100644 index 0000000000000000000000000000000000000000..219865572d134fd727a6192ff01f539322e3a780 GIT binary patch literal 3783 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 literal 0 HcmV?d00001 diff --git a/public/images/user/male.jpg b/public/images/user/male.jpg new file mode 100644 index 0000000000000000000000000000000000000000..46d58f26ee38288c5bf2df069e6a7d25bf5ef099 GIT binary patch literal 4136 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 X#=BIQwe5HrP^?{gp7sR$-?#riPNQ%> literal 0 HcmV?d00001 diff --git a/public/images/user/user_bg_info.jpg b/public/images/user/user_bg_info.jpg new file mode 100644 index 0000000000000000000000000000000000000000..00bb9351c03d9bda7624ffcb6d81add931b94780 GIT binary patch literal 23985 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 a { + display: block; + padding: 0 10px 0 32px; + height:49px; + line-height:49px; + color: #333; + font-size:16px; + background: #f8f8f8; + border:1px solid #e5e5e5; + border-bottom:none; +} +.users_accordion > li:hover > a{ + color: #3b94d6; + background: #fff; +} +.users_accordion > li:target > a, +.users_accordion > li > a.active { + color: #3b94d6; + background: #fff; + border:1px solid #e5e5e5; + border-left:3px solid #3b94d6; + border-bottom:none; +} +.users_accordion li{ position:relative;} + +.users_accordion li > a span { + margin-top:15px; + font-size:12px; + padding: 0 10px; + background: #dbdbdb; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; + margin-left:10px; + color: #333; +} +.users_accordion > li:hover > a span, +.users_accordion > li:target > a span, +.users_accordion > li > a.active span { + margin-left:10px; + color: #333; + background: #dbdbdb; +} +/* Images */ +.users_accordion > li > a:before { + position: absolute; + top: 0; + left: 0; + content: ''; + width: 24px; + height: 50px; + margin: 4px 8px; + background-repeat: no-repeat; + background-image:url(/images/user/icons_user_leftnav.png); + background-position: 5px 15px; +} +.users_accordion li.user_icons_course > a:before { background-position: 5px 15px; } +.users_accordion li.user_icons_course:hover > a:before, +.users_accordion li.user_icons_course:target > a:before, +.users_accordion li.user_icons_course > a.active:before { background-position: -25px 15px; } +.users_accordion li.user_icons_new > a:before { background-position: 5px -48px; } +.users_accordion li.user_icons_new:hover > a:before, +.users_accordion li.user_icons_new:target > a:before, +.users_accordion li.user_icons_new > a.active:before { background-position: -25px -48px; } +.users_accordion li.user_icons_addclass > a:before { background-position: 5px -87px; } +.users_accordion li.user_icons_addclass:hover > a:before, +.users_accordion li.user_icons_addclass:target > a:before, +.users_accordion li.user_icons_addclass > a.active:before { background-position: -25px -87px; } +.users_accordion li.user_icons_myhw > a:before { background-position: 5px -124px; } +.users_accordion li.user_icons_myhw:hover > a:before, +.users_accordion li.user_icons_myhw:target > a:before, +.users_accordion li.user_icons_myhw > a.active:before { background-position: -25px -124px; } +.users_accordion li.user_icons_project > a:before { background-position: 5px -167px; } +.users_accordion li.user_icons_project:hover > a:before, +.users_accordion li.user_icons_project:target > a:before, +.users_accordion li.user_icons_project > a.active:before { background-position: -25px -167px; } +.users_accordion li.user_icons_addproject > a:before { background-position: 5px -205px; } +.users_accordion li.user_icons_addproject:hover > a:before, +.users_accordion li.user_icons_addproject:target > a:before, +.users_accordion li.user_icons_addproject > a.active:before { background-position: -25px -205px; } +.users_accordion li.user_icons_myissues > a:before { background-position: 5px -246px; } +.users_accordion li.user_icons_myissues:hover > a:before, +.users_accordion li.user_icons_myissues:target > a:before, +.users_accordion li.user_icons_myissues > a.active:before { background-position: -25px -246px; } +.users_accordion li.user_icons_mes > a:before { background-position: 5px -289px; } +.users_accordion li.user_icons_mes:hover > a:before, +.users_accordion li.user_icons_mes:target > a:before, +.users_accordion li.user_icons_mes > a.active:before { background-position: -25px -289px; } +/* Sub Menu */ +.sub-menu li a { + color: #797979; + background: #f8f8f8; + height:39px; + line-height:39px; + font-size:14px; +} +.sub-menu li a:hover,.sub-menu li a:target { background:#fff; color:#3b94d6;} +.sub-menu li:last-child a { } +.users_accordion li > .sub-menu { + display: none; +} + +.users_accordion li:target > .sub-menu { + display: block; +} +.sub-menu > li > span.user_icons_class { + padding:0; + border:none; + display:block; + position: absolute; + top:18px; + left:10px; + width:20px; + height:20px; + background:url(/images/user/icons_user_leftnav.png) 0px -34px no-repeat; +} +.sub-menu > li > a > span.user_icons_moreclass{ + display:block; + position: absolute; + top:3px; + left:96px; + width:20px; + height:10px; + background:url(/images/user/icons_user_leftnav.png) 5px -347px no-repeat; +} +a.user_editinfo{border-top:1px solid #e5e5e5; height:30px; line-height:30px; text-align:center; color:#3b94d6; width:100%; display:inline-block;} \ No newline at end of file From 3c2ab3212195d5681e8f8c54a84f363d09ac25b4 Mon Sep 17 00:00:00 2001 From: yuanke <249218296@qq.com> Date: Thu, 4 Aug 2016 11:17:50 +0800 Subject: [PATCH 47/78] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E5=8A=A8=E6=80=81?= =?UTF-8?q?=E5=88=86=E4=BA=AB=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wechat/controllers/invite_code.js | 2 +- .../wechat/controllers/project_invite_code.js | 2 +- public/javascripts/wechat/others/factory.js | 36 +++++++++++++++---- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/public/javascripts/wechat/controllers/invite_code.js b/public/javascripts/wechat/controllers/invite_code.js index 53fcd3d87..db8b99ae7 100644 --- a/public/javascripts/wechat/controllers/invite_code.js +++ b/public/javascripts/wechat/controllers/invite_code.js @@ -15,7 +15,7 @@ app.controller('InviteCodeController', ['$scope','$http', '$routeParams','config var desc = "班级邀请:"+vm.course.name+" 班级"; - common.wxConfig(desc,""); + common.wxConfig("",desc,""); // wx.ready(function(){ // wx.onMenuShareTimeline({ diff --git a/public/javascripts/wechat/controllers/project_invite_code.js b/public/javascripts/wechat/controllers/project_invite_code.js index 39a4c1aaf..dea2e9d64 100644 --- a/public/javascripts/wechat/controllers/project_invite_code.js +++ b/public/javascripts/wechat/controllers/project_invite_code.js @@ -15,7 +15,7 @@ app.controller('ProjectInviteCodeController', ['$scope','$http', '$routeParams', var desc = "项目邀请:"+vm.project.name+" 项目"; - common.wxConfig(desc,""); + common.wxConfig("",desc,""); // wx.ready(function(){ // wx.onMenuShareTimeline({ diff --git a/public/javascripts/wechat/others/factory.js b/public/javascripts/wechat/others/factory.js index 9fa8d09aa..5e5e6d4bf 100644 --- a/public/javascripts/wechat/others/factory.js +++ b/public/javascripts/wechat/others/factory.js @@ -201,8 +201,8 @@ app.factory('common', ['$http', 'auth', '$routeParams','rms','config','wx', func var loadData = function(id,replytype,page){ loadCommonData(id, args.type,replytype,page).then(function successCallback(response) { console.log(response.data); - - var tmptile = "动态"; + //--------------分享内容定制------------- + var tmptile = "分享动态"; var imgUrl = ""; if(response.data.data.title){ @@ -221,11 +221,25 @@ app.factory('common', ['$http', 'auth', '$routeParams','rms','config','wx', func imgUrl = window.g_localhost+response.data.data.author.img_url; } - var desc = tmpname+":"+tmptile; + if(response.data.data.content){ + desc = response.data.data.content.replace(/<[^>]+>/g,"").replace(/\s*/g,"").replace(/ /g,""); + } + + if(response.data.data.description){ + desc = response.data.data.description.replace(/<[^>]+>/g,"").replace(/\s*/g,"").replace(/ /g,""); + } + + if(desc.length > 30){ + desc = desc.substring(0,30)+"..."; + } + + var title = tmpname+":"+tmptile; console.log("desc = "+desc); console.log("imgUrl= "+imgUrl); - wxConfig(desc); + wxConfig(title,desc,imgUrl); + + //--------------分享内容定制------------- args.loadCallback(response.data); }, function errorCallback(response) { }); @@ -330,7 +344,15 @@ app.factory('common', ['$http', 'auth', '$routeParams','rms','config','wx', func }; - var wxConfig = function(desc,imgUrl){ + var wxConfig = function(title,desc,imgUrl){ + + if(title == null || title == ""){ + title = 'Trustie创新实践平台'; + } + + if(desc == null || desc == ""){ + desc = 'Trustie创新实践平台'; + } if(imgUrl == null || imgUrl == ""){ imgUrl = 'http://www.trustie.net/images/logo2.png'; @@ -338,7 +360,7 @@ app.factory('common', ['$http', 'auth', '$routeParams','rms','config','wx', func wx.ready(function(){ wx.onMenuShareTimeline({ - title: 'Trustie创新实践平台', // 分享标题 + title: title, // 分享标题 // link: 'http://www.trustie.net/', // 分享链接 imgUrl: imgUrl, // 分享图标 success: function () { @@ -350,7 +372,7 @@ app.factory('common', ['$http', 'auth', '$routeParams','rms','config','wx', func }); wx.onMenuShareAppMessage({ - title: 'Trustie创新实践平台', // 分享标题 + title: title, // 分享标题 desc: desc, // 分享描述 // link: '', // 分享链接 // imgUrl: '', // 分享图标 From 12a9c95c01135708625b10adfcfd4bcda8d00ed0 Mon Sep 17 00:00:00 2001 From: yuanke <249218296@qq.com> Date: Thu, 4 Aug 2016 14:07:35 +0800 Subject: [PATCH 48/78] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E5=8F=8A=E7=8F=AD=E7=BA=A7=E9=82=80=E8=AF=B7=E7=A0=81=E7=9B=B8?= =?UTF-8?q?=E5=85=B3BUG=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/wechats_controller.rb | 2 +- app/services/courses_service.rb | 2 +- app/services/projects_service.rb | 2 +- app/services/wechat_service.rb | 4 ++-- public/javascripts/wechat/others/factory.js | 1 + 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/controllers/wechats_controller.rb b/app/controllers/wechats_controller.rb index 190502a3c..c5ef8c24e 100644 --- a/app/controllers/wechats_controller.rb +++ b/app/controllers/wechats_controller.rb @@ -306,7 +306,7 @@ class WechatsController < ActionController::Base role = 5 ps = ProjectsService.new - status = ps.join_project({invite_code: project.invite_code}, user) + status = ps.join_project({role:5, invite_code: project.invite_code}, user) if status != 0 raise ProjectsService::JoinProjectError.message(status) end diff --git a/app/services/courses_service.rb b/app/services/courses_service.rb index e0455022f..9ed6faaa6 100644 --- a/app/services/courses_service.rb +++ b/app/services/courses_service.rb @@ -226,7 +226,7 @@ class CoursesService end else CourseMessage.create(:user_id => apply_user.id, :course_id => c.id, :viewed => false,:content=> messages.content,:course_message_id=>current_user.id,:course_message_type=>'CourseRequestDealResult',:status=>2) - message.update_attributes(:status=>2,:viewed=>1) + messages.update_attributes(:status=>2,:viewed=>1) if integer_ids.include?(9) message = "您已拒绝教师"+apply_user.show_name+",加入班级" else diff --git a/app/services/projects_service.rb b/app/services/projects_service.rb index e732571c5..dd1e6c2d7 100644 --- a/app/services/projects_service.rb +++ b/app/services/projects_service.rb @@ -150,7 +150,7 @@ class ProjectsService if !AppliedProject.where(:project_id => project.id, :user_id => current_user.id).first.nil? status = 8 else - AppliedProject.create(:user_id => current_user.id, :project_id => project.id, :role => params[:role_id]) + AppliedProject.create(:user_id => current_user.id, :project_id => project.id, :role => params[:role]) status = 7 end diff --git a/app/services/wechat_service.rb b/app/services/wechat_service.rb index afb0d0f8c..9a6351391 100644 --- a/app/services/wechat_service.rb +++ b/app/services/wechat_service.rb @@ -142,7 +142,7 @@ class WechatService def three_keys_template(openid, template_id, type, id, first, key1, key2, key3, remark="",uid) tmpurl = "#{Setting.protocol}://#{Setting.host_name}/wechat/user_activities#/#{type}/#{id}" if uid && uid != 0 - tmpurl = tmpurl + "&user_id="+uid.to_s + tmpurl = "#{Setting.protocol}://#{Setting.host_name}/wechat/user_activities#/#{type}?id=#{id}"+ "&user_id="+uid.to_s end data = { @@ -179,7 +179,7 @@ class WechatService def four_keys_template(openid, template_id, type, id, first, key1, key2, key3, key4, remark="",uid) tmpurl = "#{Setting.protocol}://#{Setting.host_name}/wechat/user_activities#/#{type}/#{id}" if uid && uid != 0 - tmpurl = tmpurl + "&user_id="+uid.to_s + tmpurl = "#{Setting.protocol}://#{Setting.host_name}/wechat/user_activities#/#{type}?id=#{id}"+ "&user_id="+uid.to_s end data = { diff --git a/public/javascripts/wechat/others/factory.js b/public/javascripts/wechat/others/factory.js index 5e5e6d4bf..7ac0a3bdb 100644 --- a/public/javascripts/wechat/others/factory.js +++ b/public/javascripts/wechat/others/factory.js @@ -221,6 +221,7 @@ app.factory('common', ['$http', 'auth', '$routeParams','rms','config','wx', func imgUrl = window.g_localhost+response.data.data.author.img_url; } + var desc = "" if(response.data.data.content){ desc = response.data.data.content.replace(/<[^>]+>/g,"").replace(/\s*/g,"").replace(/ /g,""); } From e4a414e550b81ad59c341fbb872f0308e646bd2d Mon Sep 17 00:00:00 2001 From: yuanke <249218296@qq.com> Date: Thu, 4 Aug 2016 14:37:04 +0800 Subject: [PATCH 49/78] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E8=8F=9C=E5=8D=95?= =?UTF-8?q?=E8=B7=B3=E5=85=A5=E5=8A=A0=E5=85=A5=E9=A1=B9=E7=9B=AE=E5=92=8C?= =?UTF-8?q?=E7=8F=AD=E7=BA=A7=E7=95=8C=E9=9D=A2=E7=82=B9=E5=8F=96=E6=B6=88?= =?UTF-8?q?=E8=A6=81=E8=83=BD=E8=BF=94=E5=9B=9E=E5=85=AC=E4=BC=97=E5=8F=B7?= =?UTF-8?q?=E7=95=8C=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/assets/wechat/review_class_member.html | 2 +- public/assets/wechat/review_project_member.html | 2 +- public/javascripts/wechat/controllers/class_list.js | 2 +- public/javascripts/wechat/controllers/join_class.js | 11 +++++++++-- public/javascripts/wechat/controllers/join_project.js | 10 ++++++++-- public/javascripts/wechat/controllers/project_list.js | 2 +- 6 files changed, 21 insertions(+), 8 deletions(-) diff --git a/public/assets/wechat/review_class_member.html b/public/assets/wechat/review_class_member.html index 81d2e03d6..c13571e4c 100644 --- a/public/assets/wechat/review_class_member.html +++ b/public/assets/wechat/review_class_member.html @@ -6,7 +6,7 @@
      角色
      • -
      • +
      拒绝 diff --git a/public/assets/wechat/review_project_member.html b/public/assets/wechat/review_project_member.html index b03fdd276..5b8113eb4 100644 --- a/public/assets/wechat/review_project_member.html +++ b/public/assets/wechat/review_project_member.html @@ -6,7 +6,7 @@
      角色
      • -
      • +
      拒绝 diff --git a/public/javascripts/wechat/controllers/class_list.js b/public/javascripts/wechat/controllers/class_list.js index 98910242f..48e778f9d 100644 --- a/public/javascripts/wechat/controllers/class_list.js +++ b/public/javascripts/wechat/controllers/class_list.js @@ -94,7 +94,7 @@ app.controller('ClassListController', ['$scope', 'config', 'auth', '$http', '$lo // } // }); - $location.path("/join_class"); + $location.path("/join_class").search({tag: 1}); }; diff --git a/public/javascripts/wechat/controllers/join_class.js b/public/javascripts/wechat/controllers/join_class.js index bbdaae7c5..3f1a28387 100644 --- a/public/javascripts/wechat/controllers/join_class.js +++ b/public/javascripts/wechat/controllers/join_class.js @@ -1,10 +1,11 @@ -app.controller('JoinClassController', ['$scope', '$http', 'auth', 'config', 'alertService','$location','$routeParams','rms', function($scope, $http, auth, config, alertService, $location,$routeParams, rms){ +app.controller('JoinClassController', ['$scope', '$http', 'auth', 'config', 'alertService','$location','$routeParams','rms','wx', function($scope, $http, auth, config, alertService, $location,$routeParams, rms,wx){ var vm = $scope; // vm.current_edit_member = rms.get('current_edit_member'); vm.current_edit_member = null; + var tag = $routeParams.tag; vm.alertService = alertService.create(); @@ -17,7 +18,13 @@ app.controller('JoinClassController', ['$scope', '$http', 'auth', 'config', 'ale // vm.alertService.showMessage('提示', '您确定不对角色进行变更吗?', function(){ // window.history.back(); // }); - window.history.back(); + if(tag){ + window.history.back(); + } + else{ + wx.closeWindow(); + } + }; vm.joinClass = function(){ diff --git a/public/javascripts/wechat/controllers/join_project.js b/public/javascripts/wechat/controllers/join_project.js index 2b167e04c..f27c535c5 100644 --- a/public/javascripts/wechat/controllers/join_project.js +++ b/public/javascripts/wechat/controllers/join_project.js @@ -1,6 +1,6 @@ -app.controller('JoinProjectController', ['$scope', '$http', 'auth', 'config', 'alertService','$location','$routeParams','rms', function($scope, $http, auth, config, alertService, $location,$routeParams, rms){ +app.controller('JoinProjectController', ['$scope', '$http', 'auth', 'config', 'alertService','$location','$routeParams','rms','wx', function($scope, $http, auth, config, alertService, $location,$routeParams, rms,wx){ var vm = $scope; // vm.current_edit_member = rms.get('current_edit_member'); @@ -9,9 +9,15 @@ app.controller('JoinProjectController', ['$scope', '$http', 'auth', 'config', 'a vm.role_id = 0; vm.alertService = alertService.create(); vm.invite_code = ""; + var tag = $routeParams.tag; vm.cancel = function(){ - window.history.back(); + if(tag){ + window.history.back(); + } + else{ + wx.closeWindow(); + } }; vm.join_project = function(){ diff --git a/public/javascripts/wechat/controllers/project_list.js b/public/javascripts/wechat/controllers/project_list.js index 2d0568f16..6ff7495e4 100644 --- a/public/javascripts/wechat/controllers/project_list.js +++ b/public/javascripts/wechat/controllers/project_list.js @@ -75,7 +75,7 @@ app.controller('ProjectListController', ['$scope', 'config', 'auth', '$http', '$ // } // } // }); - $location.path("/join_project"); + $location.path("/join_project").search({tag: 1}); }; vm.onSetting = function (project) { From ee019cd3645b5fd8191156b07c3b810e780ba624 Mon Sep 17 00:00:00 2001 From: yuanke <249218296@qq.com> Date: Thu, 4 Aug 2016 14:47:39 +0800 Subject: [PATCH 50/78] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E7=89=88=E5=BE=AE=E4=BF=A1=E5=8A=A0=E5=85=A5=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E5=AE=A1=E6=A0=B8=E9=80=9A=E7=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/services/projects_service.rb | 2 +- config/wechat.yml.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/services/projects_service.rb b/app/services/projects_service.rb index dd1e6c2d7..b1d917b08 100644 --- a/app/services/projects_service.rb +++ b/app/services/projects_service.rb @@ -161,7 +161,7 @@ class ProjectsService end end else - status = 4 + status = 1 end status end diff --git a/config/wechat.yml.test b/config/wechat.yml.test index 3d1861d67..8dbd9850f 100644 --- a/config/wechat.yml.test +++ b/config/wechat.yml.test @@ -22,7 +22,7 @@ default: &default class_notice: "8LVu33l6bP-56SDomVgHn-yJc57YpCwwJ81rAJgRONk" create_class_notice: "9CDIvHIKiGwPEQWRw_-wieec1o50tMXQPPZIfECKu0I" create_project_notice: "R2ZaQKJfDJgujPcHWPzadKHIRkIyj2CjX2o_qIuRqig" - project_review_notice: "cwpAHzdrYQo0Gc5ZKCBHMYEe8NjlOF6KpMGklMch8RM" + project_review_notice: "ip192wVXTav3qchgUn9_7B6lFfTlCZjwL7A1tncTOuc" production: <<: *default From 55afb84aef17846ad9ebb7e886aed0518fb29f87 Mon Sep 17 00:00:00 2001 From: yuanke <249218296@qq.com> Date: Thu, 4 Aug 2016 15:32:25 +0800 Subject: [PATCH 51/78] =?UTF-8?q?=E6=A8=A1=E7=89=88=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E6=A0=87=E9=A2=98=E5=8A=A0=E4=B8=8A=E5=8F=A5=E5=8F=B7=EF=BC=8C?= =?UTF-8?q?=E5=AE=A1=E6=A0=B8=E6=A8=A1=E7=89=88=E6=B6=88=E6=81=AF=E5=86=8D?= =?UTF-8?q?=E6=AC=A1=E7=82=B9=E5=87=BB=E6=98=BE=E7=A4=BA=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/applied_project.rb | 2 +- app/services/courses_service.rb | 2 +- public/assets/wechat/review_class_member.html | 8 ++++++++ public/assets/wechat/review_project_member.html | 10 ++++++++-- .../wechat/controllers/review_class_member.js | 10 ++++++++++ .../wechat/controllers/review_project_member.js | 11 +++++++++++ 6 files changed, 39 insertions(+), 4 deletions(-) diff --git a/app/models/applied_project.rb b/app/models/applied_project.rb index abab2ab6f..a6eef8417 100644 --- a/app/models/applied_project.rb +++ b/app/models/applied_project.rb @@ -17,7 +17,7 @@ class AppliedProject < ActiveRecord::Base count = ShieldWechatMessage.where("container_type='User' and container_id=#{member.user_id} and shield_type='Project' and shield_id=#{self.project_id}").count if count == 0 ws = WechatService.new - ws.project_review_notice member.user_id, "review_project_member", self.project_id, "项目成员审批通知", self.project.name, self.user.show_name, format_time(Time.now),"点击查看申请详情。",self.user.id + ws.project_review_notice member.user_id, "review_project_member", self.project_id, "项目成员审批通知。", self.project.name, self.user.show_name, format_time(Time.now),"点击查看申请详情。",self.user.id end #-------------------------------------------- end diff --git a/app/services/courses_service.rb b/app/services/courses_service.rb index 9ed6faaa6..2f5745892 100644 --- a/app/services/courses_service.rb +++ b/app/services/courses_service.rb @@ -615,7 +615,7 @@ class CoursesService rolename = role_ids.include?("7") ? "助教" : "教师" content = current_user.show_name + "申请以"+rolename+"身份加入班级,等待您的审批。" ws = WechatService.new - ws.class_notice tea_user.id, "review_class_member", course.id, "班级成员审批通知", course.name, tea_user.show_name, format_time(Time.now), content, "点击查看申请详情。",current_user.id + ws.class_notice tea_user.id, "review_class_member", course.id, "班级成员审批通知。", course.name, tea_user.show_name, format_time(Time.now), content, "点击查看申请详情。",current_user.id end end #-------------------------------------------- diff --git a/public/assets/wechat/review_class_member.html b/public/assets/wechat/review_class_member.html index c13571e4c..85d16fb64 100644 --- a/public/assets/wechat/review_class_member.html +++ b/public/assets/wechat/review_class_member.html @@ -14,5 +14,13 @@
      +
      +
      {{current_course.name}}
      +
      {{tip_2}}
      +
      + +
      {{tip_1}}
      + +
      diff --git a/public/assets/wechat/review_project_member.html b/public/assets/wechat/review_project_member.html index 5b8113eb4..e7c1dd6bf 100644 --- a/public/assets/wechat/review_project_member.html +++ b/public/assets/wechat/review_project_member.html @@ -1,7 +1,7 @@
      -
      -
      {{project.name}}
      +
      +
      {{current_project.name}}
      {{current_review_member.realname == "" ? current_review_member.name : current_review_member.realname}}
      角色
        @@ -14,6 +14,12 @@
      +
      +
      {{current_project.name}}
      +
      {{tip_2}}
      +
      + +
      {{tip_1}}
      diff --git a/public/javascripts/wechat/controllers/review_class_member.js b/public/javascripts/wechat/controllers/review_class_member.js index 6e8cb16eb..ab44b9572 100644 --- a/public/javascripts/wechat/controllers/review_class_member.js +++ b/public/javascripts/wechat/controllers/review_class_member.js @@ -10,6 +10,9 @@ app.controller('ReviewClassMemberController', ['$scope', '$http', 'auth', 'confi vm.alertService = alertService.create(); + vm.tip_1 = ""; + vm.tip_2 = ""; + var course_id = $routeParams.id; var user_id = $routeParams.user_id; @@ -25,6 +28,9 @@ app.controller('ReviewClassMemberController', ['$scope', '$http', 'auth', 'confi else{ vm.alertService.showMessage('提示', response.data.message); } + if(!vm.current_course){ + vm.tip_1 = "该班级不存在或已被删除"; + } } ); @@ -43,6 +49,10 @@ app.controller('ReviewClassMemberController', ['$scope', '$http', 'auth', 'confi console.log("review_member_info"); console.log(response.data.data); } + + if(!vm.current_review_member){ + vm.tip_2 = "该申请不存在或已被处理"; + } }); diff --git a/public/javascripts/wechat/controllers/review_project_member.js b/public/javascripts/wechat/controllers/review_project_member.js index 113aa426b..e6998a9d8 100644 --- a/public/javascripts/wechat/controllers/review_project_member.js +++ b/public/javascripts/wechat/controllers/review_project_member.js @@ -10,6 +10,9 @@ app.controller('ReviewProjectMemberController', ['$scope', '$http', 'auth', 'con vm.alertService = alertService.create(); + vm.tip_1 = ""; + vm.tip_2 = ""; + var project_id = $routeParams.id; var user_id = $routeParams.user_id; @@ -26,6 +29,10 @@ app.controller('ReviewProjectMemberController', ['$scope', '$http', 'auth', 'con vm.alertService.showMessage('提示', response.data.message); } + if(!vm.current_project){ + vm.tip_1 = "该项目不存在或已被删除"; + } + } ); } @@ -43,6 +50,10 @@ app.controller('ReviewProjectMemberController', ['$scope', '$http', 'auth', 'con console.log("review_member_info"); console.log(response.data.data); } + + if(!vm.current_review_member){ + vm.tip_2 = "该申请不存在或已被处理"; + } }); } From b7c05fed4aeacd4c518f9d8eaaac71a898434404 Mon Sep 17 00:00:00 2001 From: cxt Date: Thu, 4 Aug 2016 16:33:51 +0800 Subject: [PATCH 52/78] =?UTF-8?q?=E9=A6=96=E9=A1=B5=E6=A0=B7=E5=BC=8F?= =?UTF-8?q?=E5=92=8Cjs=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/layouts/_user_courses.html.erb | 76 +++++++++++----------- app/views/layouts/_user_projects.html.erb | 61 ++++++++--------- app/views/layouts/new_base_user.html.erb | 40 +++++++----- public/images/user/icons_user_leftnav.png | Bin 25180 -> 25966 bytes public/images/user/user_navmore_icons.png | Bin 0 -> 19619 bytes public/stylesheets/css/structure.css | 42 +++++++++--- public/stylesheets/syllabus.css | 4 +- 7 files changed, 127 insertions(+), 96 deletions(-) create mode 100644 public/images/user/user_navmore_icons.png diff --git a/app/views/layouts/_user_courses.html.erb b/app/views/layouts/_user_courses.html.erb index eb8dc80b8..b3b21547e 100644 --- a/app/views/layouts/_user_courses.html.erb +++ b/app/views/layouts/_user_courses.html.erb @@ -7,87 +7,85 @@ <% count = ShieldActivity.where("container_type='User' and container_id=#{user.id} and shield_type='Course' and shield_id=#{course.id}").count %> <% wechat_count = ShieldWechatMessage.where("container_type='User' and container_id=#{user.id} and shield_type='Course' and shield_id=#{course.id}").count %> -
        -
      • -
        - 提示 + 提示
        • 教师、助教角色需要班级管理员审批
        • 学生角色无需管理员审批
        • diff --git a/public/assets/wechat/new_project.html b/public/assets/wechat/new_project.html index e14f17508..103651ef9 100644 --- a/public/assets/wechat/new_project.html +++ b/public/assets/wechat/new_project.html @@ -6,14 +6,14 @@
          项目名称
          完成
          - 项目功能特性(微信版) + 项目功能特性(微信版)
          • 创建项目、加入项目
          • 邀请成员、修改角色
          • 浏览、回复项目动态
          • 点赞、分享项目动态
          - 更多项目特性(浏览器版) + 更多项目特性(浏览器版)
          • 发布任务、问题跟踪
          • 代码托管、质量分析
          • From bb46aa4745d14074c5c4cddeeed308a9ef071cb0 Mon Sep 17 00:00:00 2001 From: yuanke <249218296@qq.com> Date: Thu, 4 Aug 2016 18:09:54 +0800 Subject: [PATCH 56/78] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E7=82=B9=E5=87=BB?= =?UTF-8?q?=E5=B7=B2=E5=AE=A1=E6=89=B9=E6=A8=A1=E7=89=88=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E8=BF=9B=E5=85=A5=E7=95=8C=E9=9D=A2=E6=98=BE=E7=A4=BA=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/mobile/apis/courses.rb | 7 ++-- app/api/mobile/apis/projects.rb | 6 ++-- app/services/courses_service.rb | 8 +++-- app/services/projects_service.rb | 14 +++++--- public/assets/wechat/review_class_member.html | 34 ++++++++++++------ .../assets/wechat/review_project_member.html | 35 +++++++++++++------ .../wechat/controllers/review_class_member.js | 13 ++++--- .../controllers/review_project_member.js | 16 +++++++-- 8 files changed, 93 insertions(+), 40 deletions(-) diff --git a/app/api/mobile/apis/courses.rb b/app/api/mobile/apis/courses.rb index 402702659..575048211 100644 --- a/app/api/mobile/apis/courses.rb +++ b/app/api/mobile/apis/courses.rb @@ -208,9 +208,10 @@ module Mobile authenticate! cs = CoursesService.new - reviewer = cs.get_reviewer_info(params) - present :data, reviewer, with: Mobile::Entities::User - present :status, 0 + result = cs.get_reviewer_info(params) + + present :data, result[:reviewer], with: Mobile::Entities::User + present :status,result[:status] end desc "处理教师或助教的身份申请" diff --git a/app/api/mobile/apis/projects.rb b/app/api/mobile/apis/projects.rb index 8f6e7d96d..05d4036f9 100644 --- a/app/api/mobile/apis/projects.rb +++ b/app/api/mobile/apis/projects.rb @@ -207,9 +207,9 @@ module Mobile authenticate! ps = ProjectsService.new - reviewer = ps.get_reviewer_info params - present :data, reviewer, with: Mobile::Entities::User - present :status, 0 + result = ps.get_reviewer_info(params,current_user) + present :data, result[:reviewer], with: Mobile::Entities::User + present :status, result[:status] end desc "处理管理或开发的身份申请" diff --git a/app/services/courses_service.rb b/app/services/courses_service.rb index 2f5745892..c6854f3dd 100644 --- a/app/services/courses_service.rb +++ b/app/services/courses_service.rb @@ -152,12 +152,14 @@ class CoursesService end def get_reviewer_info params + status = -1 info = nil c = Course.find(params[:course_id]) if c - messages = CourseMessage.where("course_id=? and course_message_id = ? and course_message_type = 'JoinCourseRequest' and status = 0 ",params[:course_id],params[:user_id]).first - + messages = CourseMessage.where("course_id=? and course_message_id = ? and course_message_type = 'JoinCourseRequest' ",params[:course_id],params[:user_id]).last if messages + #status 0未处理 1同意 2 通过 + status = messages.status user = User.find(params[:user_id]) if user img_url = url_to_avatar(user) @@ -175,7 +177,7 @@ class CoursesService end end - info + {status:status,reviewer:info} end def deal_join_apply params,current_user diff --git a/app/services/projects_service.rb b/app/services/projects_service.rb index b1d917b08..1b342c122 100644 --- a/app/services/projects_service.rb +++ b/app/services/projects_service.rb @@ -198,12 +198,16 @@ class ProjectsService review_members end - def get_reviewer_info params + def get_reviewer_info params,current_user + status = -1 info = nil project = Project.find(params[:project_id]) if project - messages = AppliedProject.where(:project_id=> project.id, :user_id=>params[:user_id]).first - if messages + # messages = AppliedProject.where(:project_id=> project.id, :user_id=>params[:user_id]).first + #status 1未处理 5拒绝 7同意 + applied_message = AppliedMessage.where(:user_id => current_user.id, :project_id => project.id, :applied_user_id=>params[:user_id],:applied_type => "AppliedProject").last + if applied_message + status = applied_message.status user = User.find(params[:user_id]) if user img_url = url_to_avatar(user) @@ -214,13 +218,13 @@ class ProjectsService :work_unit => work_unit, :mail => user.mail, :location => location, role_name: "", name: user.show_name, - roles_id: messages.role, + roles_id: applied_message.role, :brief_introduction => user.user_extensions.brief_introduction,:realname=>user.realname} end end end - info + {status:status,reviewer:info} end def deal_join_apply params,current_user diff --git a/public/assets/wechat/review_class_member.html b/public/assets/wechat/review_class_member.html index 85d16fb64..06ce99018 100644 --- a/public/assets/wechat/review_class_member.html +++ b/public/assets/wechat/review_class_member.html @@ -1,16 +1,30 @@
            -
            {{current_course.name}}
            -
            {{current_review_member.realname == "" ? current_review_member.name : current_review_member.realname}}
            -
            角色
            -
              -
            • -
            • -
            -
            - 拒绝 - 同意 +
            +
            {{current_course.name}}
            +
            {{current_review_member.realname == "" ? current_review_member.name : current_review_member.realname}}
            +
            角色
            +
              +
            • +
            • +
            +
            + 拒绝 + 同意 +
            +
            +
            +
            审批结果
            +
            该申请已被处理,处理情况如下: +
              +
            • 申请用户: {{current_review_member.realname == "" ? current_review_member.name : current_review_member.realname}}
            • +
            • 申请角色: {{current_review_member.roles_id == 7 ? "助教" : "教师" }}
            • +
            • 班级名称: {{current_course.name}}
            • +
            • 处理结果: {{status == 1 ? "同意" : "拒绝"}}
            • +
            +
            +
            知道了
            diff --git a/public/assets/wechat/review_project_member.html b/public/assets/wechat/review_project_member.html index e7c1dd6bf..d50a04fa4 100644 --- a/public/assets/wechat/review_project_member.html +++ b/public/assets/wechat/review_project_member.html @@ -1,16 +1,31 @@
            -
            {{current_project.name}}
            -
            {{current_review_member.realname == "" ? current_review_member.name : current_review_member.realname}}
            -
            角色
            -
              -
            • -
            • -
            -
            - 拒绝 - 同意 +
            +
            {{current_project.name}}
            +
            {{current_review_member.realname == "" ? current_review_member.name : current_review_member.realname}}
            +
            角色
            +
              +
            • +
            • +
            +
            + 拒绝 + 同意 +
            +
            + +
            +
            审批结果
            +
            该申请已被处理,处理情况如下: +
              +
            • 申请用户: {{current_review_member.realname == "" ? current_review_member.name : current_review_member.realname}}
            • +
            • 申请角色: {{current_review_member.roles_id == 3 ? "管理人员" : "开发人员" }}
            • +
            • 项目名称: {{current_project.name}}
            • +
            • 处理结果: {{status == 7 ? "同意" : "拒绝"}}
            • +
            +
            +
            知道了
            diff --git a/public/javascripts/wechat/controllers/review_class_member.js b/public/javascripts/wechat/controllers/review_class_member.js index ab44b9572..44704c32d 100644 --- a/public/javascripts/wechat/controllers/review_class_member.js +++ b/public/javascripts/wechat/controllers/review_class_member.js @@ -15,6 +15,7 @@ app.controller('ReviewClassMemberController', ['$scope', '$http', 'auth', 'confi var course_id = $routeParams.id; var user_id = $routeParams.user_id; + vm.status = 0; if(!vm.current_course){ $http.get(config.apiUrl+ 'courses/'+course_id+"?token="+auth.token()).then( @@ -42,20 +43,20 @@ app.controller('ReviewClassMemberController', ['$scope', '$http', 'auth', 'confi course_id: course_id, user_id:user_id }).then(function(response){ - if(response.data.status!=0){ + if(response.data.status==-1){ vm.alertService.showMessage('提示', response.data.message); } else { vm.current_review_member = response.data.data; + vm.status = response.data.status; console.log("review_member_info"); console.log(response.data.data); } if(!vm.current_review_member){ - vm.tip_2 = "该申请不存在或已被处理"; + vm.tip_2 = "该申请不存在"; } }); - } vm.deal = function(result){ @@ -67,7 +68,7 @@ app.controller('ReviewClassMemberController', ['$scope', '$http', 'auth', 'confi }).then(function(response) { if (response.data.status == 0) { vm.alertService.showMessage('提示', response.data.message, function () { - $location.path("/class").search({id: course_id,tag:1}); + $location.path("/class").search({id: course_id,tag: 1}); }); } else{ @@ -75,4 +76,8 @@ app.controller('ReviewClassMemberController', ['$scope', '$http', 'auth', 'confi } }); }; + + vm.goClassMemberList = function(){ + $location.path("/class").search({id: course_id,tag: 1}); + }; }] ); \ No newline at end of file diff --git a/public/javascripts/wechat/controllers/review_project_member.js b/public/javascripts/wechat/controllers/review_project_member.js index e6998a9d8..2428c09d0 100644 --- a/public/javascripts/wechat/controllers/review_project_member.js +++ b/public/javascripts/wechat/controllers/review_project_member.js @@ -15,6 +15,7 @@ app.controller('ReviewProjectMemberController', ['$scope', '$http', 'auth', 'con var project_id = $routeParams.id; var user_id = $routeParams.user_id; + vm.status = 1; if(!vm.current_project){ $http.get(config.apiUrl+ 'projects/'+project_id+"?token="+auth.token()).then( @@ -43,16 +44,17 @@ app.controller('ReviewProjectMemberController', ['$scope', '$http', 'auth', 'con project_id: project_id, user_id:user_id }).then(function(response){ - if(response.data.status!=0){ + if(response.data.status==-1){ vm.alertService.showMessage('提示', response.data.message); } else { + vm.status = response.data.status; vm.current_review_member = response.data.data; console.log("review_member_info"); console.log(response.data.data); } if(!vm.current_review_member){ - vm.tip_2 = "该申请不存在或已被处理"; + vm.tip_2 = "该申请不存在"; } }); } @@ -80,4 +82,14 @@ app.controller('ReviewProjectMemberController', ['$scope', '$http', 'auth', 'con } }); }; + + vm.goProjectMemberList = function(){ + rms.save("project_master_members",[]); + rms.save("project_develop_members",[]); + rms.save("project_report_members",[]); + rms.save("review_master_members",[]); + rms.save("review_develop_members",[]); + rms.save("tab_num",null); + $location.path("/project").search({id: project_id,tag: 1}); + }; }] ); \ No newline at end of file From f9bfe278c0ec1e7e868ba3256a257368abfa1ea8 Mon Sep 17 00:00:00 2001 From: cxt Date: Fri, 5 Aug 2016 10:03:47 +0800 Subject: [PATCH 57/78] =?UTF-8?q?=E5=A4=9A=E9=87=8D=E8=BA=AB=E4=BB=BD?= =?UTF-8?q?=E7=9A=84=E5=AD=A6=E7=94=9F=E5=8C=BF=E8=AF=84=E5=8F=98=E4=B8=BA?= =?UTF-8?q?=E4=BA=86=E6=95=99=E8=BE=85=E8=AF=84=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/student_work_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/student_work_controller.rb b/app/controllers/student_work_controller.rb index e2dd23552..3d87b007d 100644 --- a/app/controllers/student_work_controller.rb +++ b/app/controllers/student_work_controller.rb @@ -828,7 +828,7 @@ class StudentWorkController < ApplicationController if User.current.admin? @new_score.reviewer_role = 1 else - role = User.current.members.where("course_id = ?",@course.id).first.roles.first.name + role = User.current.members.where("course_id = ?",@course.id).first.roles.where("is_current = 1").first.name @new_score.reviewer_role = get_role_by_name(role) end if @score From 56452d69f4ec1de78abb70cdbfd5e89da6cfd1a2 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 5 Aug 2016 14:11:35 +0800 Subject: [PATCH 58/78] =?UTF-8?q?=E4=BE=A7=E5=AF=BC=E8=88=AA=E5=AD=97?= =?UTF-8?q?=E4=BD=93=E5=A4=A7=E5=B0=8F=EF=BC=8C=E9=A2=9C=E8=89=B2=E6=9B=B4?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/courses/_course_activity_users.html.erb | 4 ++-- app/views/courses/_course_heroes.html.erb | 4 ++-- app/views/layouts/base_courses.html.erb | 2 +- public/stylesheets/css/common.css | 6 +++--- public/stylesheets/sy_public.css | 1 - public/stylesheets/syllabus.css | 14 +++++++------- 6 files changed, 15 insertions(+), 16 deletions(-) diff --git a/app/views/courses/_course_activity_users.html.erb b/app/views/courses/_course_activity_users.html.erb index 8b4df3e83..67ec2ede9 100644 --- a/app/views/courses/_course_activity_users.html.erb +++ b/app/views/courses/_course_activity_users.html.erb @@ -3,9 +3,9 @@

              <% if (User.current.logged? && course.open_student == 1) || (User.current.member_of_course?(course)) || User.current.admin? %> - <%= link_to "班级活跃度", course_member_path(course, :role => 2, :sort_type => 'act_score'), :class => 'sy_cblack' %> + <%= link_to "班级活跃度", course_member_path(course, :role => 2, :sort_type => 'act_score'), :class => 'fontGrey3' %> <% else %> - 班级活跃度 + 班级活跃度 <% end %> 积分规则
              diff --git a/app/views/courses/_course_heroes.html.erb b/app/views/courses/_course_heroes.html.erb index 4699c12d2..bd285f9b0 100644 --- a/app/views/courses/_course_heroes.html.erb +++ b/app/views/courses/_course_heroes.html.erb @@ -3,9 +3,9 @@

                <% if (User.current.logged? && course.open_student == 1) || (User.current.member_of_course?(course)) || User.current.admin? %> - <%= link_to "班级英雄榜", course_member_path(course, :role => 2), :class => 'sy_cblack' %> + <%= link_to "班级英雄榜", course_member_path(course, :role => 2), :class => 'fontGrey3' %> <% else %> - 班级英雄榜 + 班级英雄榜 <% end %> 积分规则

                diff --git a/app/views/layouts/base_courses.html.erb b/app/views/layouts/base_courses.html.erb index 2972045aa..86a0a5518 100644 --- a/app/views/layouts/base_courses.html.erb +++ b/app/views/layouts/base_courses.html.erb @@ -131,7 +131,7 @@ <%# 课程英雄榜 %> <%= render :partial => 'courses/course_heroes', :locals => {:course => @course} %>
                -

                班级推荐

                +

                班级推荐

                <%= render :partial => 'courses/recommendation', :locals => {:course => @course} %>
                diff --git a/public/stylesheets/css/common.css b/public/stylesheets/css/common.css index 7db3c4370..1c7394ed3 100644 --- a/public/stylesheets/css/common.css +++ b/public/stylesheets/css/common.css @@ -94,9 +94,7 @@ h4{ font-size:14px;}/*color:#3b3b3b;*/ .flow_hidden{ width:300px;overflow:hidden; white-space: nowrap; text-overflow:ellipsis;} .white_space{white-space:nowrap;} .pr {position:relative;} -.fontGrey3 {color:#484848;} -a.linkGrey6 {color:#484848 !important;} -a.linkGrey6:hover {color:#ffffff !important;} + .markPopup {width:290px; height:auto; padding:5px 0px 15px 15px; background-color:#ffffff; z-index:1000;} .markInput { outline:none; border:1px solid #e6e6e6; height:30px; width:50px; color:#3d3c3c; margin-bottom:10px; text-align:center; margin-right:5px; padding-left:0;} .markPercentage {margin:10px 0; border:1px solid #e6e6e6; width:70px; height:30px; outline:none; font-size:12px; color:#3d3c3c;} @@ -400,6 +398,7 @@ a:hover.c_grey{ color:#333;} .fontGrey4{color:#999999;} .fontGrey5 {color:#a1a1a1;} .fontGrey6 {color:#7a7a7a;} +.fontGrey7 {color:#555;} .fontBlue {color:#3498db;} span.newsBlack {color:#4b4b4b; font-size:13px; font-weight:bold} a.underline {text-decoration:underline;} @@ -407,6 +406,7 @@ a.fontBlue {color:#297fb8;} .fontBlue2 {color:#269ac9 !important;} a.fontGrey {color:#cecece;} a.fontGrey2 {color:#888888;} +a.fontGrey3 {color:#555;} a.link-black {color:#000;} a.link-black:hover {color:#3b94d6;} a.link-blue {color:#3b94d6;} diff --git a/public/stylesheets/sy_public.css b/public/stylesheets/sy_public.css index f52fc6699..42365faa4 100644 --- a/public/stylesheets/sy_public.css +++ b/public/stylesheets/sy_public.css @@ -4,7 +4,6 @@ .sy_corange{ color: #ee4a1f;} .sy_f14{ font-size: 14px;} .sy_f16{ font-size: 16px;} -a.sy_cgrey{ color: #888;} a:hover.sy_cgrey{ color:#ee4a1f;} a.sy_corange{ color: #ee4a1f; } a:hover.sy_corange{ text-decoration:underline;} diff --git a/public/stylesheets/syllabus.css b/public/stylesheets/syllabus.css index dad467c68..d0f8d0286 100644 --- a/public/stylesheets/syllabus.css +++ b/public/stylesheets/syllabus.css @@ -399,10 +399,10 @@ a:hover.sy_btn_orange{ .accordion li > a { display: block; padding: 0 10px 0 40px; - height:49px; + height:45px; line-height:49px; - color: #333; - font-size:16px; + color: #555; + font-size:14px; background: #f8f8f8; border:1px solid #e5e5e5; border-bottom:none; @@ -425,19 +425,19 @@ a:hover.sy_btn_orange{ margin-top:15px; font-size:12px; padding: 0 10px; - background: #dbdbdb; + background: #ccc; -webkit-border-radius: 15px; -moz-border-radius: 15px; border-radius: 15px; margin-left:10px; - color: #333; + color: #888; } .accordion > li:hover > a span, .accordion > li:target > a span, .accordion > li > a.active span { margin-left:10px; - color: #333; - background: #dbdbdb; + color: #888; + background: #ccc; } /* Images */ .accordion > li > a:before { From 82644bcd8189b734aad0dc3bef09f9e6221964e5 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 5 Aug 2016 14:36:01 +0800 Subject: [PATCH 59/78] =?UTF-8?q?=E5=8A=A0=E5=85=A5=E7=8F=AD=E7=BA=A7?= =?UTF-8?q?=E3=80=81=E9=A1=B9=E7=9B=AE=E5=BC=B9=E6=A1=86=E5=8F=AF=E6=8B=96?= =?UTF-8?q?=E6=8B=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/javascripts/application.js | 51 +++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/public/javascripts/application.js b/public/javascripts/application.js index 6ac978568..fb6bb6864 100644 --- a/public/javascripts/application.js +++ b/public/javascripts/application.js @@ -1501,9 +1501,60 @@ function pop_box_new(value, Width, Height){ $('#ajax-modal').siblings().remove(); $('#ajax-modal').parent().css({"top": h+"px","left": w+"px","padding":"0","border":"none","position":"fixed"}); $('#ajax-modal').css({"padding":"0"}); + $('#ajax-modal').parent().attr("id","popupWrap"); //拖拽 + function Drag(id) { + this.div = document.getElementById(id); + if (this.div) { + this.div.style.cursor = "move"; + this.div.style.position = "fixed"; + } + this.disX = 0; + this.disY = 0; + var _this = this; + this.div.onmousedown = function (evt) { + _this.getDistance(evt); + document.onmousemove = function (evt) { + _this.setPosition(evt); + } + _this.div.onmouseup = function () { + _this.clearEvent(); + } + } + } + Drag.prototype.getDistance = function (evt) { + var oEvent = evt || event; + this.disX = oEvent.clientX - this.div.offsetLeft; + this.disY = oEvent.clientY - this.div.offsetTop; + } + Drag.prototype.setPosition = function (evt) { + var oEvent = evt || event; + var l = oEvent.clientX - this.disX; + var t = oEvent.clientY - this.disY; + if (l <= 0) { + l = 0; + } + else if (l >= document.documentElement.clientWidth - this.div.offsetWidth) { + l = document.documentElement.clientWidth - this.div.offsetWidth; + } + if (t <= 0) { + t = 0; + } + else if (t >= document.documentElement.clientHeight - this.div.offsetHeight) { + t = document.documentElement.clientHeight - this.div.offsetHeight; + } + this.div.style.left = l + "px"; + this.div.style.top = t + "px"; + } + Drag.prototype.clearEvent = function () { + this.div.onmouseup = null; + document.onmousemove = null; + } + window.onload = function () { + new Drag("popupWrap"); + } } // 公共提示弹框样式 From be5e74897adf4323e8cf287d0eaac8193d533484 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 5 Aug 2016 15:26:15 +0800 Subject: [PATCH 60/78] =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E5=BC=B9=E6=A1=86?= =?UTF-8?q?=E4=BD=8D=E7=BD=AE=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/stylesheets/css/public.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/stylesheets/css/public.css b/public/stylesheets/css/public.css index cc27955d5..405d469d2 100644 --- a/public/stylesheets/css/public.css +++ b/public/stylesheets/css/public.css @@ -263,7 +263,7 @@ div.flash.warning, .conflict { /*弹出框*/ .black_overlay{display:none;position:fixed;top:0px;left:0px;width:100%;height:100%;background-color:black;z-index:1001;-moz-opacity:0.8;opacity:.80;filter:alpha(opacity=80);} .white_content{display:none;position:fixed;top:15%;left:30%;width:420px;height: auto; margin-bottom:20px;padding:16px;border:3px solid #269ac9;background-color:white;z-index:1002;overflow:auto;} -.white_content02{display:none;position:fixed;top:15%;left:30%;width:200px;height: auto; margin-bottom:20px;padding:10px;border:3px solid #269ac9;background-color:white;z-index:1002;overflow:auto; width:456px;} +.white_content02{display:none;position:fixed;top:25%;left:40%;width:200px;height: auto; margin-bottom:20px;padding:10px;border:3px solid #269ac9;background-color:white;z-index:1002;overflow:auto; width:456px;} .newhwork_content{ display:none;position:fixed;top:15%;left:30%;width:600px;height: auto; margin-bottom:20px;padding:16px;border:3px solid #269ac9;background-color:white;z-index:1002;overflow:auto;} .floatbox{ width:420px; border:3px solid #269ac9; background:#fff; padding:5px;} a.box_close{ display:block; float:right; width:16px; height:16px; background:url(../images/img_floatbox.png) 0 0 no-repeat;} From 0d86a28c549de76af67aab3257fd487741480b9a Mon Sep 17 00:00:00 2001 From: cxt Date: Fri, 5 Aug 2016 16:12:53 +0800 Subject: [PATCH 61/78] =?UTF-8?q?=E6=88=91=E7=9A=84=E4=BD=9C=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/users_controller.rb | 106 +++++++++++++++++- app/helpers/application_helper.rb | 43 +++++++ app/helpers/users_helper.rb | 13 +++ app/models/homework_common.rb | 14 +++ app/models/user.rb | 7 ++ app/views/layouts/new_base_user.html.erb | 4 +- app/views/layouts/static_base.html.erb | 4 +- .../users/_homework_repository_list.html.erb | 2 +- .../users/_manage_homework_list.html.erb | 45 ++++++++ app/views/users/_my_homework_list.html.erb | 11 ++ app/views/users/_my_homework_sort.html.erb | 22 ++++ app/views/users/_my_homeworks_search.html.erb | 36 ++++++ .../users/_receive_homework_list.html.erb | 36 ++++++ .../manage_or_receive_homeworks.html.erb | 53 +++++++++ .../users/manage_or_receive_homeworks.js.erb | 11 ++ app/views/users/my_homeworks.html.erb | 28 +++++ app/views/users/my_homeworks.js.erb | 1 + app/views/users/search_m_r_homeworks.js.erb | 7 ++ app/views/users/user_homeworks.html.erb | 18 +-- config/routes.rb | 3 + public/javascripts/application.js | 21 ++++ public/stylesheets/sy_public.css | 24 ++++ 22 files changed, 494 insertions(+), 15 deletions(-) create mode 100644 app/views/users/_manage_homework_list.html.erb create mode 100644 app/views/users/_my_homework_list.html.erb create mode 100644 app/views/users/_my_homework_sort.html.erb create mode 100644 app/views/users/_my_homeworks_search.html.erb create mode 100644 app/views/users/_receive_homework_list.html.erb create mode 100644 app/views/users/manage_or_receive_homeworks.html.erb create mode 100644 app/views/users/manage_or_receive_homeworks.js.erb create mode 100644 app/views/users/my_homeworks.html.erb create mode 100644 app/views/users/my_homeworks.js.erb create mode 100644 app/views/users/search_m_r_homeworks.js.erb diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 8d131fd4e..932617671 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -41,7 +41,8 @@ class UsersController < ApplicationController :activity_score_index, :influence_score_index, :score_index,:show_new_score, :topic_new_score_index, :project_new_score_index, :activity_new_score_index, :influence_new_score_index, :score_new_index,:user_projects_index,:user_resource, :user_courses4show,:user_projects4show,:user_course_activities,:user_project_activities,:user_feedback4show,:user_visitorlist,:user_messages,:edit_brief_introduction, - :user_import_homeworks,:user_search_homeworks,:user_import_resource, :user_system_messages,:choose_user_course,:user_courselist,:user_projectlist,:sort_syllabus_list] + :user_import_homeworks,:user_search_homeworks,:user_import_resource, :user_system_messages,:choose_user_course,:user_courselist,:user_projectlist,:sort_syllabus_list, + :my_homeworks,:manage_or_receive_homeworks,:search_m_r_homeworks] before_filter :auth_user_extension, only: :show #before_filter :rest_user_score, only: :show #before_filter :select_entry, only: :user_projects @@ -598,7 +599,7 @@ class UsersController < ApplicationController if(params[:type].blank? || params[:type] == "1") #我的题库 courses = @user.courses.where("is_delete = 1") course_ids = courses.empty? ? "(-1)" : "(" + courses.map{|course| course.id}.join(",") + ")" - @homeworks = HomeworkCommon.where("user_id = #{@user.id} and course_id not in #{course_ids}").order("#{@order} #{@b_sort}") + @homeworks = HomeworkCommon.where("user_id = #{@user.id} and publish_time <= '#{Date.today}' and course_id not in #{course_ids}").order("#{@order} #{@b_sort}") elsif params[:type] == "2" #公共题库 visible_course = Course.where("is_delete = 0") visible_course_ids = visible_course.empty? ? "(-1)" : "(" + visible_course.map{|course| course.id}.join(",") + ")" @@ -1524,6 +1525,107 @@ class UsersController < ApplicationController render :action=>'user_course_activities',:layout=>nil end + #首页-》我的作业 + def my_homeworks + tea_courses = @user.courses.visible.not_deleted.select{|course| @user.has_teacher_role(course)} + tea_course_ids = tea_courses.empty? ? "(-1)" : "(" + tea_courses.map{|course| course.id}.join(',') + ")" + @manage_homeworks = HomeworkCommon.where("course_id in #{tea_course_ids}").order("created_at desc").limit(5) + stu_courses = @user.courses.visible.not_deleted.select{|course| @user.has_student_role(course)} + stu_course_ids = stu_courses.empty? ? "(-1)" : "(" + stu_courses.map{|course| course.id}.join(',') + ")" + @receive_homeworks = HomeworkCommon.where("course_id in #{stu_course_ids} and publish_time <= '#{Date.today}'").order("created_at desc").limit(5) + if (@manage_homeworks.empty? && @receive_homeworks.empty?) || (@receive_homeworks.empty?) || (!@manage_homeworks.empty? && !@receive_homeworks.empty? && @manage_homeworks.first.publish_time > @receive_homeworks.first.publish_time) + @manage_pre = true + else + @manage_pre = false + end + respond_to do |format| + format.js + format.html {render :layout => 'static_base'} + end + end + + #我管理/收到的作业 + def manage_or_receive_homeworks + @order,@b_sort,@type = params[:order] || "created_at",params[:sort] || "desc",params[:type] || 1 + @r_sort = @b_sort == "desc" ? "asc" : "desc" + @type = @type.to_i + if @type == 1 + tea_courses = @user.courses.visible.not_deleted.select{|course| @user.has_teacher_role(course)} + tea_course_ids = tea_courses.empty? ? "(-1)" : "(" + tea_courses.map{|course| course.id}.join(',') + ")" + @homeworks = HomeworkCommon.where("course_id in #{tea_course_ids}").order("#{@order} #{@b_sort}") + else + stu_courses = @user.courses.visible.not_deleted.select{|course| @user.has_student_role(course)} + stu_course_ids = stu_courses.empty? ? "(-1)" : "(" + stu_courses.map{|course| course.id}.join(',') + ")" + @homeworks = HomeworkCommon.where("course_id in #{stu_course_ids} and publish_time <= '#{Date.today}'").order("#{@order} #{@b_sort}") + end + if params[:property] + all_homework_ids = @homeworks.empty? ? "(-1)" : "(" + @homeworks.map{|h| h.id}.join(",") + ")" + if params[:property] == "1" + @homeworks = HomeworkCommon.find_by_sql("select * from homework_commons where id in #{all_homework_ids} and homework_type = 1") + elsif params[:property] == "2" + @homeworks = HomeworkCommon.find_by_sql("select * from homework_commons where id in #{all_homework_ids} and homework_type = 2") + elsif params[:property] == "3" + @homeworks = HomeworkCommon.find_by_sql("select * from homework_commons where id in #{all_homework_ids} and homework_type = 3") + end + end + @limit = 10 + @is_remote = true + @hw_count = @homeworks.count + @hw_pages = Paginator.new @hw_count, @limit, params['page'] || 1 + @offset ||= @hw_pages.offset + @homeworks = paginateHelper @homeworks,@limit + @search = "" + @property = params[:property] + respond_to do |format| + format.js + format.html {render :layout => 'static_base'} + end + end + + #搜索作业 + def search_m_r_homeworks + @order,@b_sort,@type = params[:order] || "created_at",params[:sort] || "desc",params[:type].to_i || 1 + @r_sort = @b_sort == "desc" ? "asc" : "desc" + search = params[:name].to_s.strip.downcase + type_ids = (params[:property]=="" || params[:property].nil? || params[:property]=="0") ? "(1, 2, 3)" : "(" + params[:property] + ")" + if @type == 1 + tea_courses = @user.courses.visible.not_deleted.select{|course| @user.has_teacher_role(course)} + tea_course_ids = tea_courses.empty? ? "(-1)" : "(" + tea_courses.map{|course| course.id}.join(',') + ")" + #user_ids = hw_publisher_user_ids search, tea_course_ids + @homeworks = HomeworkCommon.where("course_id in #{tea_course_ids} and homework_type in #{type_ids} and name like '%#{search}%'").order("#{@order} #{@b_sort}") + else + stu_courses = @user.courses.visible.not_deleted.select{|course| @user.has_student_role(course)} + stu_course_ids = stu_courses.empty? ? "(-1)" : "(" + stu_courses.map{|course| course.id}.join(',') + ")" + #user_ids = hw_publisher_user_ids search, stu_course_ids + @homeworks = HomeworkCommon.where("course_id in #{stu_course_ids} and homework_type in #{type_ids} and publish_time <= '#{Date.today}' and name like '%#{search}%'") + if @order == "status" + @homeworks.each do |homework| + work = cur_user_works_for_homework homework + if work.blank? + homework[:infocount] = 0 + else + homework[:infocount] = 1 + end + end + @b_sort == "asc" ? (@homeworks = @homeworks.sort{|x,y| x[:infocount] <=> y[:infocount] }) : (@homeworks = @homeworks.sort{|x,y| y[:infocount] <=> x[:infocount]}) + @homeworks = sortby_time_countcommon_nosticky @homeworks,"created_at" + else + @homeworks = @homeworks.order("#{@order} #{@b_sort}") + end + end + @limit = 10 + @is_remote = true + @hw_count = @homeworks.count + @hw_pages = Paginator.new @hw_count, @limit, params['page'] || 1 + @offset ||= @hw_pages.offset + @homeworks = paginateHelper @homeworks,@limit + @search = search + @property = params[:property] + respond_to do |format| + format.js + end + end + def user_feedback4show query = @user.journals_for_messages if params[:lastid]!=nil && !params[:lastid].empty? diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index d64d95223..319ff921a 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -2736,7 +2736,39 @@ module ApplicationHelper else link_to "作品(#{count})",student_work_index_url_in_org(homework.id),:class => "c_blue" end + end + #根据传入作业确定显示为提交作品、补交作品、查看作品等 + def student_for_homework_common homework + if User.current.member_of_course?(homework.course) + work = cur_user_works_for_homework homework + project = cur_user_projects_for_homework homework + if work.nil? && Time.parse(homework.end_time.to_s).strftime("%Y-%m-%d") >= Time.now.strftime("%Y-%m-%d") + if homework.homework_type ==3 && project.nil? && homework.homework_detail_group.base_on_project == 1 + link_to "查看详情", homework_common_index_path(:course_id => homework.course_id), :class => 'hw_btn_green2 fr mt5',:title => '查看分组作业详情', :target => '_blank' + else + link_to "提交作品", new_student_work_url_without_domain(homework.id),:class => 'hw_btn_green2 fr mt5', :target => '_blank' + end + elsif work.nil? && Time.parse(homework.end_time.to_s).strftime("%Y-%m-%d") < Time.now.strftime("%Y-%m-%d") + if homework.homework_type ==3 && project.nil? && homework.homework_detail_group.base_on_project == 1 + link_to "查看详情", homework_common_index_path(:course_id => homework.course_id), :class => 'hw_btn_green2 fr mt5',:title => '查看分组作业详情', :target => '_blank' + else + link_to "补交作品", new_student_work_url_without_domain(homework.id),:class => 'btn_orange_big fr mt5', :target => '_blank' + end + else + if homework.homework_detail_manual && homework.homework_detail_manual.comment_status == 2 #匿评作业,且作业状态不是在开启匿评之前 + link_to "作品匿评", student_work_index_url_in_org(homework.id), :class => 'hw_btn_green2 fr mt5', :title => "开启匿评后不可修改作品", :target => '_blank' + elsif homework.homework_detail_manual && homework.homework_detail_manual.comment_status == 3 + link_to "查看作品",student_work_index_url_in_org(homework.id), :class => 'hw_btn_green2 fr mt5', :title => "匿评已结束", :target => '_blank' + elsif homework.homework_type == 2 && Time.parse(homework.end_time.to_s).strftime("%Y-%m-%d") >= Time.now.strftime("%Y-%m-%d")#编程作业不能修改作品 + link_to "修改作品", new_student_work_url_without_domain(homework.id),:class => 'hw_btn_green2 fr mt5', :target => '_blank' + elsif Time.parse(homework.end_time.to_s).strftime("%Y-%m-%d") >= Time.now.strftime("%Y-%m-%d") && work.user_id == User.current.id + link_to "修改作品", edit_student_work_url_without_domain(work.id),:class => 'hw_btn_green2 fr mt5', :target => '_blank' + else + link_to "查看作品", student_work_index_url_in_org(homework.id), :class => 'hw_btn_green2 fr mt5', :title => "作业截止后不可修改作品", :target => '_blank' + end + end + end end def relate_project homework,is_teacher,is_in_course,user_activity_id,course_activity @@ -2788,6 +2820,17 @@ module ApplicationHelper homework.student_work_projects.where("user_id = ?",User.current).first end + #获取当前作业的提交截止时间/互评截止时间 + def cur_homework_end_time homework + str = "" + if homework.anonymous_comment == 0 && homework.end_time < Date.today && homework.homework_detail_manual + str = "互评截止:#{format_date homework.homework_detail_manual.evaluation_end}" + else + str = "提交截止:#{homework.end_time ? (format_date homework.end_time) : '       --       '}" + end + str + end + def file_preview_tag(file, html_options={}) if %w(pdf pptx doc docx xls xlsx).any?{|x| file.filename.downcase.end_with?(x)} link_to '预览', download_named_attachment_path(file.id, file.filename, preview: true),html_options diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb index 91743289a..88fe87c6a 100644 --- a/app/helpers/users_helper.rb +++ b/app/helpers/users_helper.rb @@ -742,4 +742,17 @@ module UsersHelper end syllabuses end + + #获取按作业的发布者排序的用户ID + def hw_publisher_user_ids search, course_ids + if search && search != "" + all_homeworks = HomeworkCommon.where("course_id in #{course_ids}") + all_user_ids = all_homeworks.map{|hw| hw.user_id} + user_str_ids = search_user_by_name all_user_ids, search + user_ids = user_str_ids.empty? ? "(-1)" : "(" + user_str_ids.join(",") + ")" + else + user_ids = "(-1)" + end + return user_ids + end end diff --git a/app/models/homework_common.rb b/app/models/homework_common.rb index a915b1545..86aab8260 100644 --- a/app/models/homework_common.rb +++ b/app/models/homework_common.rb @@ -34,6 +34,20 @@ class HomeworkCommon < ActiveRecord::Base after_save :act_as_course_activity after_destroy :delete_kindeditor_assets + #作业类型 + def homework_type_ch + type = self.homework_type + case type + when 1 + type = "普通" + when 2 + type = "编程" + when 3 + type = "分组" + end + type + end + def act_as_activity self.acts << Activity.new(:user_id => self.user_id) end diff --git a/app/models/user.rb b/app/models/user.rb index a4b7f3b25..57663f3eb 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -926,6 +926,13 @@ class User < Principal !role.blank? end + #是否具有学生角色 + def has_student_role(course) + member = course.members.where("user_id = #{self.id}").first + role = MemberRole.where("member_id = #{member.id} and role_id = 10") + !role.blank? + end + # Return true if the user is allowed to do the specified action on a specific context # Action can be: # * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit') diff --git a/app/views/layouts/new_base_user.html.erb b/app/views/layouts/new_base_user.html.erb index 16cb2206e..50e788e2f 100644 --- a/app/views/layouts/new_base_user.html.erb +++ b/app/views/layouts/new_base_user.html.erb @@ -184,7 +184,9 @@ <%= link_to "加入班级",join_private_courses_courses_path,:remote => true, :method => "post"%> <% if @user == User.current %> -
              • 我的作业
              • +
              • + <%=link_to '我的作业', my_homeworks_user_path(@user.id), :target => "_blank" %> +
              • <% end %> <% end %>
              diff --git a/app/views/layouts/static_base.html.erb b/app/views/layouts/static_base.html.erb index 0dc3b93d3..e0b8b468f 100644 --- a/app/views/layouts/static_base.html.erb +++ b/app/views/layouts/static_base.html.erb @@ -7,7 +7,7 @@ <%= csrf_meta_tag %> <%= favicon %> - <%= stylesheet_link_tag 'jquery/jquery-ui-1.9.2', 'application', 'nyan','prettify','syllabus','sy_public', :media => 'all' %> + <%= stylesheet_link_tag 'jquery/jquery-ui-1.9.2', 'application', 'nyan','prettify', :media => 'all' %> <%= stylesheet_link_tag 'rtl', :media => 'all' if l(:direction) == 'rtl' %> <%= javascript_heads %> <%= javascript_include_tag "jquery.leanModal.min",'prettify' %> @@ -16,7 +16,7 @@ <%= call_hook :view_layouts_base_html_head %> <%= yield :header_tags -%> - <%= stylesheet_link_tag 'css/common','css/structure','css/public','css/popup', :media => 'all'%> + <%= stylesheet_link_tag 'css/common','css/structure','css/public','css/popup','syllabus','sy_public', :media => 'all'%> \ No newline at end of file diff --git a/app/views/users/_receive_homework_list.html.erb b/app/views/users/_receive_homework_list.html.erb new file mode 100644 index 000000000..f992c2af8 --- /dev/null +++ b/app/views/users/_receive_homework_list.html.erb @@ -0,0 +1,36 @@ +
              + <% if homeworks.empty? %> +
              +

              暂无可显示的内容~

              + <% else %> + <% homeworks.each do |homework| %> +
                + +
                +

                + <%= link_to homework.name, student_work_index_path(:homework => homework.id), :class => 'sy_cblack', :target => '_blank' %> +

                +
                +

                + 来源: + <%= link_to homework.course.name, course_path(homework.course), :target => '_blank', :class => 'hw_cgrey hw_classname fl mr15' %> + 类别:<%=homework.homework_type_ch %> + <% my_work = cur_user_works_for_homework(homework) %> + 状态:<%= my_work ? '已提交' : '未提交' %> + 作品:<%=homework.student_works.has_committed.count %> + 成绩: + <% if my_work && !my_work.work_score.nil? %> + <%= format("%.1f",my_work.work_score.to_f) %> + <% else %> + -- + <% end %> + 发布时间:<%= format_date homework.publish_time %> + <%=cur_homework_end_time homework %> +

                +
                + <%= student_for_homework_common homework %> +
                +
              + <% end %> + <% end %> +
              \ No newline at end of file diff --git a/app/views/users/manage_or_receive_homeworks.html.erb b/app/views/users/manage_or_receive_homeworks.html.erb new file mode 100644 index 000000000..c380fd05d --- /dev/null +++ b/app/views/users/manage_or_receive_homeworks.html.erb @@ -0,0 +1,53 @@ + +
              + + + +
              +
              + <%=render :partial=>'my_homeworks_search', :locals=>{:type => @type,:property => nil,:order => @order, :search => ''} %> +
              + +
              + <% if @type == 1 %> + <%= render :partial => "manage_homework_list", :locals => {:homeworks => @homeworks} %> + <% else %> + <%= render :partial => "receive_homework_list", :locals => {:homeworks => @homeworks} %> + <% end %> +
              + +
              +
              +
                + <%= pagination_links_full @hw_pages, @hw_count, :per_page_links => false, :remote => @is_remote, :flag => true, :is_new => true%> +
              +
              +
              +
              +
              +
              \ No newline at end of file diff --git a/app/views/users/manage_or_receive_homeworks.js.erb b/app/views/users/manage_or_receive_homeworks.js.erb new file mode 100644 index 000000000..6f719d1fc --- /dev/null +++ b/app/views/users/manage_or_receive_homeworks.js.erb @@ -0,0 +1,11 @@ +<% if @type == 1 %> +$("#my_homework_list").html('<%= escape_javascript(render :partial => "manage_homework_list", :locals => {:homeworks => @homeworks})%>'); +<% else %> +$("#my_homework_list").html('<%= escape_javascript(render :partial => "receive_homework_list", :locals => {:homeworks => @homeworks})%>'); +<% end %> +$("#homework_list_ref_pages").html('<%= pagination_links_full @hw_pages, @hw_count, :per_page_links => false, :remote => @is_remote, :flag => true, :is_new => true %>'); +$("#my_homework_sort").html('<%= escape_javascript( render :partial => 'users/my_homework_sort', :locals => {:type => @type,:property => @property,:order => @order,:search => @search})%>'); +$("#homework_type_all").attr('href','<%= manage_or_receive_homeworks_user_path(@user, :type => @type, :property => 0) %>'); +$("#homework_type_nor").attr('href','<%= manage_or_receive_homeworks_user_path(@user, :type => @type, :property => 1) %>'); +$("#homework_type_pro").attr('href','<%= manage_or_receive_homeworks_user_path(@user, :type => @type, :property => 2) %>'); +$("#homework_type_gro").attr('href','<%= manage_or_receive_homeworks_user_path(@user, :type => @type, :property => 3) %>'); \ No newline at end of file diff --git a/app/views/users/my_homeworks.html.erb b/app/views/users/my_homeworks.html.erb new file mode 100644 index 000000000..ccf06adfd --- /dev/null +++ b/app/views/users/my_homeworks.html.erb @@ -0,0 +1,28 @@ + +
              + + +
              + <%=render :partial => 'my_homework_list' %> +
              +
              \ No newline at end of file diff --git a/app/views/users/my_homeworks.js.erb b/app/views/users/my_homeworks.js.erb new file mode 100644 index 000000000..6da3f6526 --- /dev/null +++ b/app/views/users/my_homeworks.js.erb @@ -0,0 +1 @@ +$("#hw_tab_con_1").html("<%= escape_javascript(render :partial => 'users/my_homework_list') %>"); \ No newline at end of file diff --git a/app/views/users/search_m_r_homeworks.js.erb b/app/views/users/search_m_r_homeworks.js.erb new file mode 100644 index 000000000..4729e53ce --- /dev/null +++ b/app/views/users/search_m_r_homeworks.js.erb @@ -0,0 +1,7 @@ +<% if @type == 1 %> +$("#my_homework_list").html('<%= escape_javascript(render :partial => "manage_homework_list", :locals => {:homeworks => @homeworks})%>'); +<% else %> +$("#my_homework_list").html('<%= escape_javascript(render :partial => "receive_homework_list", :locals => {:homeworks => @homeworks})%>'); +<% end %> +$("#homework_list_ref_pages").html('<%= pagination_links_full @hw_pages, @hw_count, :per_page_links => false, :remote => @is_remote, :flag => true, :is_new => true %>'); +$("#my_homework_sort").html('<%= escape_javascript( render :partial => 'users/my_homework_sort', :locals => {:type => @type,:property => @property,:order => @order,:search => @search})%>'); diff --git a/app/views/users/user_homeworks.html.erb b/app/views/users/user_homeworks.html.erb index 5f6e1d60e..cc4356401 100644 --- a/app/views/users/user_homeworks.html.erb +++ b/app/views/users/user_homeworks.html.erb @@ -1,4 +1,4 @@ -<%= stylesheet_link_tag 'css/common','css/structure','css/public','css/org','repository' %> +<%= stylesheet_link_tag 'css/org','repository' %>