├── .gitattributes ├── .gitignore ├── .idea └── workspace.xml ├── README.md ├── config.py ├── errors.py ├── exampleImage ├── discuss.png ├── index.png ├── plan.png └── recommend.png ├── main.py ├── sql ├── insert_choose.sql ├── insert_edu_stu_plan.sql ├── insert_education_plan.sql ├── insert_loginformation.sql ├── insert_student.sql └── schema.sql ├── static ├── css │ ├── register-login.css │ └── style1.css ├── images │ ├── .DS_Store │ ├── banner2.jpg │ ├── btn.png │ ├── but_bg.png │ ├── github.jpg │ ├── guangao1.png │ ├── icon1.png │ ├── icon11.png │ ├── icon2.png │ ├── icon21.png │ ├── icon3.png │ ├── icon31.png │ ├── icon4.png │ ├── icon41.png │ ├── icon5.png │ ├── icon6.png │ ├── info_icon.png │ ├── info_icon1.png │ ├── info_icon2.png │ ├── jj_pic.jpg │ ├── logo.ico │ ├── logo.jpeg │ ├── logo.jpg │ ├── logo1.jpeg │ ├── logo1.png │ ├── logo1920.jpeg │ ├── logo220.png │ ├── lxwm_icon1.png │ ├── lxwm_icon2.png │ ├── lxwm_icon3.png │ ├── lxwm_icon4.png │ ├── lxwm_icon5.png │ ├── personal.jpg │ ├── qq.jpg │ ├── siade_bg.png │ ├── siade_bg1.png │ └── xl.jpg └── js │ ├── .DS_Store │ ├── Tree.js │ ├── actions.js │ ├── background.js │ ├── index.js │ ├── jquery-2.2.4.min.js │ ├── jquery.js │ ├── jquery.min.js │ ├── jquery.superslide.2.1.1.js │ ├── jquery1.42.min.js │ ├── layer │ ├── layer.js │ └── skin │ │ ├── default │ │ ├── icon-ext.png │ │ ├── icon.png │ │ ├── loading-0.gif │ │ ├── loading-1.gif │ │ └── loading-2.gif │ │ └── layer.css │ ├── particles.js │ └── recommedBar.js ├── templates ├── 404.html ├── 500.html ├── course_discussion.html ├── detail.html ├── index.html ├── login.html ├── manager.html ├── managerAdd.html ├── managerDelete.html ├── managerEdit.html ├── news_center.html ├── personal_information.html ├── recommed.html ├── register.html └── train_plan.html ├── utils ├── __init__.py ├── __pycache__ │ ├── __init__.cpython-36.pyc │ ├── __init__.cpython-37.pyc │ ├── config.cpython-36.pyc │ ├── config.cpython-37.pyc │ ├── map_student_course.cpython-36.pyc │ ├── map_student_course.cpython-37.pyc │ ├── query.cpython-36.pyc │ ├── query.cpython-37.pyc │ ├── recommed_module.cpython-36.pyc │ └── recommed_module.cpython-37.pyc ├── map_student_course.py ├── query.py ├── recommed_module.py ├── resource.py └── toJson.py └── 学生培养计划管理系统说明书.pdf /.gitattributes: -------------------------------------------------------------------------------- 1 | *.js linguist-language=python 2 | *.css linguist-language=python 3 | *.html linguist-language=python 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /venv 2 | /.idea 3 | -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 62 | 63 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | ":function(){return''}();return f.open(c.extend({btn:["确定","取消"],content:e,skin:"layui-layer-prompt"+j("prompt"),success:function(a){d=a.find(".layui-layer-input"),d.focus()},yes:function(c){var e=d.val();""===e?d.focus():e.length>(a.maxlength||500)?f.tips("最多输入"+(a.maxlength||500)+"个字数",d,{tips:1}):b&&b(e,c,d)}},a))},f.tab=function(a){a=a||{};var b=a.tab||{};return f.open(c.extend({type:1,skin:"layui-layer-tab"+j("tab"),title:function(){var a=b.length,c=1,d="";if(a>0)for(d=''+b[0].title+"";a>c;c++)d+=""+b[c].title+"";return d}(),content:'
    '+function(){var a=b.length,c=1,d="";if(a>0)for(d='
  • '+(b[0].content||"no content")+"
  • ";a>c;c++)d+='
  • '+(b[c].content||"no content")+"
  • ";return d}()+"
",success:function(b){var d=b.find(".layui-layer-title").children(),e=b.find(".layui-layer-tabmain").children();d.on("mousedown",function(b){b.stopPropagation?b.stopPropagation():b.cancelBubble=!0;var d=c(this),f=d.index();d.addClass("layui-layer-tabnow").siblings().removeClass("layui-layer-tabnow"),e.eq(f).show().siblings().hide(),"function"==typeof a.change&&a.change(f)})}},a))},f.photos=function(b,d,e){function g(a,b,c){var d=new Image;return d.src=a,d.complete?b(d):(d.onload=function(){d.onload=null,b(d)},void(d.onerror=function(a){d.onerror=null,c(a)}))}var h={};if(b=b||{},b.photos){var i=b.photos.constructor===Object,k=i?b.photos:{},l=k.data||[],m=k.start||0;if(h.imgIndex=(0|m)+1,b.img=b.img||"img",i){if(0===l.length)return f.msg("没有图片")}else{var n=c(b.photos),o=function(){l=[],n.find(b.img).each(function(a){var b=c(this);b.attr("layer-index",a),l.push({alt:b.attr("alt"),pid:b.attr("layer-pid"),src:b.attr("layer-src")||b.attr("src"),thumb:b.attr("src")})})};if(o(),0===l.length)return;if(d||n.on("click",b.img,function(){var a=c(this),d=a.attr("layer-index");f.photos(c.extend(b,{photos:{start:d,data:l,tab:b.tab},full:b.full}),!0),o()}),!d)return}h.imgprev=function(a){h.imgIndex--,h.imgIndex<1&&(h.imgIndex=l.length),h.tabimg(a)},h.imgnext=function(a,b){h.imgIndex++,h.imgIndex>l.length&&(h.imgIndex=1,b)||h.tabimg(a)},h.keyup=function(a){if(!h.end){var b=a.keyCode;a.preventDefault(),37===b?h.imgprev(!0):39===b?h.imgnext(!0):27===b&&f.close(h.index)}},h.tabimg=function(a){l.length<=1||(k.start=h.imgIndex-1,f.close(h.index),f.photos(b,!0,a))},h.event=function(){h.bigimg.hover(function(){h.imgsee.show()},function(){h.imgsee.hide()}),h.bigimg.find(".layui-layer-imgprev").on("click",function(a){a.preventDefault(),h.imgprev()}),h.bigimg.find(".layui-layer-imgnext").on("click",function(a){a.preventDefault(),h.imgnext()}),c(document).on("keyup",h.keyup)},h.loadi=f.load(1,{shade:"shade"in b?!1:.9,scrollbar:!1}),g(l[m].src,function(d){f.close(h.loadi),h.index=f.open(c.extend({type:1,area:function(){var e=[d.width,d.height],f=[c(a).width()-50,c(a).height()-50];return!b.full&&e[0]>f[0]&&(e[0]=f[0],e[1]=e[0]*d.height/d.width),[e[0]+"px",e[1]+"px"]}(),title:!1,shade:.9,shadeClose:!0,closeBtn:!1,move:".layui-layer-phimg img",moveType:1,scrollbar:!1,moveOut:!0,shift:5*Math.random()|0,skin:"layui-layer-photos"+j("photos"),content:'
'+(l[m].alt||
'+(l.length>1?'':"")+'
'+(l[m].alt||"")+""+h.imgIndex+"/"+l.length+"
",success:function(a,c){h.bigimg=a.find(".layui-layer-phimg"),h.imgsee=a.find(".layui-layer-imguide,.layui-layer-imgbar"),h.event(a),b.tab&&b.tab(l[m],a)},end:function(){h.end=!0,c(document).off("keyup",h.keyup)}},b))},function(){f.close(h.loadi),f.msg("当前图片地址异常
是否继续查看下一张?",{time:3e4,btn:["下一张","不看了"],yes:function(){l.length>1&&h.imgnext(!0,!0)}})})}},e.run=function(){c=jQuery,d=c(a),h.html=c("html"),f.open=function(a){var b=new g(a);return b.index}},"function"==typeof define?define(function(){return e.run(),f}):function(){e.run(),f.use("skin/layer.css")}()}(window); -------------------------------------------------------------------------------- /static/js/layer/skin/default/icon-ext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiefan-guo/studentTrainPlan/daf74215a6c683cb4f48d096d338a52d75f8a1fb/static/js/layer/skin/default/icon-ext.png -------------------------------------------------------------------------------- /static/js/layer/skin/default/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiefan-guo/studentTrainPlan/daf74215a6c683cb4f48d096d338a52d75f8a1fb/static/js/layer/skin/default/icon.png -------------------------------------------------------------------------------- /static/js/layer/skin/default/loading-0.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiefan-guo/studentTrainPlan/daf74215a6c683cb4f48d096d338a52d75f8a1fb/static/js/layer/skin/default/loading-0.gif -------------------------------------------------------------------------------- /static/js/layer/skin/default/loading-1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiefan-guo/studentTrainPlan/daf74215a6c683cb4f48d096d338a52d75f8a1fb/static/js/layer/skin/default/loading-1.gif -------------------------------------------------------------------------------- /static/js/layer/skin/default/loading-2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiefan-guo/studentTrainPlan/daf74215a6c683cb4f48d096d338a52d75f8a1fb/static/js/layer/skin/default/loading-2.gif -------------------------------------------------------------------------------- /static/js/layer/skin/layer.css: -------------------------------------------------------------------------------- 1 | /*! 2 | 3 | @Name: layer's style 4 | @Author: 贤心 5 | @Blog: sentsin.com 6 | 7 | */.layui-layer-imgbar,.layui-layer-imgtit a,.layui-layer-tab .layui-layer-title span,.layui-layer-title{text-overflow:ellipsis;white-space:nowrap}*html{background-image:url(about:blank);background-attachment:fixed}html #layui_layer_skinlayercss{display:none;position:absolute;width:1989px}.layui-layer,.layui-layer-shade{position:fixed;_position:absolute;pointer-events:auto}.layui-layer-shade{top:0;left:0;width:100%;height:100%;_height:expression(document.body.offsetHeight+"px")}.layui-layer{-webkit-overflow-scrolling:touch;top:150px;left:0;margin:0;padding:0;background-color:#fff;-webkit-background-clip:content;box-shadow:1px 1px 50px rgba(0,0,0,.3);border-radius:2px;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.3s;animation-duration:.3s}.layui-layer-close{position:absolute}.layui-layer-content{position:relative}.layui-layer-border{border:1px solid #B2B2B2;border:1px solid rgba(0,0,0,.3);box-shadow:1px 1px 5px rgba(0,0,0,.2)}.layui-layer-moves{position:absolute;border:3px solid #666;border:3px solid rgba(0,0,0,.5);cursor:move;background-color:#fff;background-color:rgba(255,255,255,.3);filter:alpha(opacity=50)}.layui-layer-load{background:url(default/loading-0.gif) center center no-repeat #fff}.layui-layer-ico{background:url(default/icon.png) no-repeat}.layui-layer-btn a,.layui-layer-dialog .layui-layer-ico,.layui-layer-setwin a{display:inline-block;*display:inline;*zoom:1;vertical-align:top}@-webkit-keyframes bounceIn{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes bounceIn{0%{opacity:0;-webkit-transform:scale(.5);-ms-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim{-webkit-animation-name:bounceIn;animation-name:bounceIn}@-webkit-keyframes bounceOut{100%{opacity:0;-webkit-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.03);transform:scale(1.03)}0%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes bounceOut{100%{opacity:0;-webkit-transform:scale(.7);-ms-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.03);-ms-transform:scale(1.03);transform:scale(1.03)}0%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim-close{-webkit-animation-name:bounceOut;animation-name:bounceOut;-webkit-animation-duration:.2s;animation-duration:.2s}@-webkit-keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);-ms-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);-ms-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-01{-webkit-animation-name:zoomInDown;animation-name:zoomInDown}@-webkit-keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.layer-anim-02{-webkit-animation-name:fadeInUpBig;animation-name:fadeInUpBig}@-webkit-keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);-ms-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);-ms-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-03{-webkit-animation-name:zoomInLeft;animation-name:zoomInLeft}@-webkit-keyframes rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}@keyframes rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);-ms-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);-ms-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}.layer-anim-04{-webkit-animation-name:rollIn;animation-name:rollIn}@keyframes fadeIn{0%{opacity:0}100%{opacity:1}}.layer-anim-05{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes shake{0%,100%{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}@keyframes shake{0%,100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);-ms-transform:translateX(10px);transform:translateX(10px)}}.layer-anim-06{-webkit-animation-name:shake;animation-name:shake}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}.layui-layer-title{padding:0 80px 0 20px;height:42px;line-height:42px;border-bottom:1px solid #eee;font-size:14px;color:#333;overflow:hidden;background-color:#F8F8F8;border-radius:2px 2px 0 0}.layui-layer-setwin{position:absolute;right:15px;*right:0;top:15px;font-size:0;line-height:initial}.layui-layer-setwin a{position:relative;width:16px;height:16px;margin-left:10px;font-size:12px;_overflow:hidden}.layui-layer-setwin .layui-layer-min cite{position:absolute;width:14px;height:2px;left:0;top:50%;margin-top:-1px;background-color:#2E2D3C;cursor:pointer;_overflow:hidden}.layui-layer-setwin .layui-layer-min:hover cite{background-color:#2D93CA}.layui-layer-setwin .layui-layer-max{background-position:-32px -40px}.layui-layer-setwin .layui-layer-max:hover{background-position:-16px -40px}.layui-layer-setwin .layui-layer-maxmin{background-position:-65px -40px}.layui-layer-setwin .layui-layer-maxmin:hover{background-position:-49px -40px}.layui-layer-setwin .layui-layer-close1{background-position:0 -40px;cursor:pointer}.layui-layer-setwin .layui-layer-close1:hover{opacity:.7}.layui-layer-setwin .layui-layer-close2{position:absolute;right:-28px;top:-28px;width:30px;height:30px;margin-left:0;background-position:-149px -31px;*right:-18px;_display:none}.layui-layer-setwin .layui-layer-close2:hover{background-position:-180px -31px}.layui-layer-btn{text-align:right;padding:0 10px 12px;pointer-events:auto}.layui-layer-btn a{height:28px;line-height:28px;margin:0 6px;padding:0 15px;border:1px solid #dedede;background-color:#f1f1f1;color:#333;border-radius:2px;font-weight:400;cursor:pointer;text-decoration:none}.layui-layer-btn a:hover{opacity:.9;text-decoration:none}.layui-layer-btn a:active{opacity:.7}.layui-layer-btn .layui-layer-btn0{border-color:#4898d5;background-color:#2e8ded;color:#fff}.layui-layer-dialog{min-width:260px}.layui-layer-dialog .layui-layer-content{position:relative;padding:20px;line-height:24px;word-break:break-all;overflow:hidden;font-size:14px;overflow-x:hidden;overflow-y:auto}.layui-layer-dialog .layui-layer-content .layui-layer-ico{position:absolute;top:16px;left:15px;_left:-40px;width:30px;height:30px}.layui-layer-ico1{background-position:-30px 0}.layui-layer-ico2{background-position:-60px 0}.layui-layer-ico3{background-position:-90px 0}.layui-layer-ico4{background-position:-120px 0}.layui-layer-ico5{background-position:-150px 0}.layui-layer-ico6{background-position:-180px 0}.layui-layer-rim{border:6px solid #8D8D8D;border:6px solid rgba(0,0,0,.3);border-radius:5px;box-shadow:none}.layui-layer-msg{min-width:180px;border:1px solid #D3D4D3;box-shadow:none}.layui-layer-hui{min-width:100px;background-color:#000;filter:alpha(opacity=60);background-color:rgba(0,0,0,.6);color:#fff;border:none}.layui-layer-hui .layui-layer-content{padding:12px 25px;text-align:center}.layui-layer-dialog .layui-layer-padding{padding:20px 20px 20px 55px;text-align:left}.layui-layer-page .layui-layer-content{position:relative;overflow:auto}.layui-layer-iframe .layui-layer-btn,.layui-layer-page .layui-layer-btn{padding-top:10px}.layui-layer-nobg{background:0 0}.layui-layer-iframe .layui-layer-content{overflow:hidden}.layui-layer-iframe iframe{display:block;width:100%}.layui-layer-loading{border-radius:100%;background:0 0;box-shadow:none;border:none}.layui-layer-loading .layui-layer-content{width:60px;height:24px;background:url(default/loading-0.gif) no-repeat}.layui-layer-loading .layui-layer-loading1{width:37px;height:37px;background:url(default/loading-1.gif) no-repeat}.layui-layer-ico16,.layui-layer-loading .layui-layer-loading2{width:32px;height:32px;background:url(default/loading-2.gif) no-repeat}.layui-layer-tips{background:0 0;box-shadow:none;border:none}.layui-layer-tips .layui-layer-content{position:relative;line-height:22px;min-width:12px;padding:5px 10px;font-size:12px;_float:left;border-radius:3px;box-shadow:1px 1px 3px rgba(0,0,0,.3);background-color:#F90;color:#fff}.layui-layer-tips .layui-layer-close{right:-2px;top:-1px}.layui-layer-tips i.layui-layer-TipsG{position:absolute;width:0;height:0;border-width:8px;border-color:transparent;border-style:dashed;*overflow:hidden}.layui-layer-tips i.layui-layer-TipsB,.layui-layer-tips i.layui-layer-TipsT{left:5px;border-right-style:solid;border-right-color:#F90}.layui-layer-tips i.layui-layer-TipsT{bottom:-8px}.layui-layer-tips i.layui-layer-TipsB{top:-8px}.layui-layer-tips i.layui-layer-TipsL,.layui-layer-tips i.layui-layer-TipsR{top:1px;border-bottom-style:solid;border-bottom-color:#F90}.layui-layer-tips i.layui-layer-TipsR{left:-8px}.layui-layer-tips i.layui-layer-TipsL{right:-8px}.layui-layer-lan[type=dialog]{min-width:280px}.layui-layer-lan .layui-layer-title{background:#4476A7;color:#fff;border:none}.layui-layer-lan .layui-layer-btn{padding:10px;text-align:right;border-top:1px solid #E9E7E7}.layui-layer-lan .layui-layer-btn a{background:#BBB5B5;border:none}.layui-layer-lan .layui-layer-btn .layui-layer-btn1{background:#C9C5C5}.layui-layer-molv .layui-layer-title{background:#009f95;color:#fff;border:none}.layui-layer-molv .layui-layer-btn a{background:#009f95}.layui-layer-molv .layui-layer-btn .layui-layer-btn1{background:#92B8B1}.layui-layer-iconext{background:url(default/icon-ext.png) no-repeat}.layui-layer-prompt .layui-layer-input{display:block;width:220px;height:30px;margin:0 auto;line-height:30px;padding:0 5px;border:1px solid #ccc;box-shadow:1px 1px 5px rgba(0,0,0,.1) inset;color:#333}.layui-layer-prompt textarea.layui-layer-input{width:300px;height:100px;line-height:20px}.layui-layer-tab{box-shadow:1px 1px 50px rgba(0,0,0,.4)}.layui-layer-tab .layui-layer-title{padding-left:0;border-bottom:1px solid #ccc;background-color:#eee;overflow:visible}.layui-layer-tab .layui-layer-title span{position:relative;float:left;min-width:80px;max-width:260px;padding:0 20px;text-align:center;cursor:default;overflow:hidden}.layui-layer-tab .layui-layer-title span.layui-layer-tabnow{height:43px;border-left:1px solid #ccc;border-right:1px solid #ccc;background-color:#fff;z-index:10}.layui-layer-tab .layui-layer-title span:first-child{border-left:none}.layui-layer-tabmain{line-height:24px;clear:both}.layui-layer-tabmain .layui-layer-tabli{display:none}.layui-layer-tabmain .layui-layer-tabli.xubox_tab_layer{display:block}.xubox_tabclose{position:absolute;right:10px;top:5px;cursor:pointer}.layui-layer-photos{-webkit-animation-duration:1s;animation-duration:1s}.layui-layer-photos .layui-layer-content{overflow:hidden;text-align:center}.layui-layer-photos .layui-layer-phimg img{position:relative;width:100%;display:inline-block;*display:inline;*zoom:1;vertical-align:top}.layui-layer-imgbar,.layui-layer-imguide{display:none}.layui-layer-imgnext,.layui-layer-imgprev{position:absolute;top:50%;width:27px;_width:44px;height:44px;margin-top:-22px;outline:0;blr:expression(this.onFocus=this.blur())}.layui-layer-imgprev{left:10px;background-position:-5px -5px;_background-position:-70px -5px}.layui-layer-imgprev:hover{background-position:-33px -5px;_background-position:-120px -5px}.layui-layer-imgnext{right:10px;_right:8px;background-position:-5px -50px;_background-position:-70px -50px}.layui-layer-imgnext:hover{background-position:-33px -50px;_background-position:-120px -50px}.layui-layer-imgbar{position:absolute;left:0;bottom:0;width:100%;height:32px;line-height:32px;background-color:rgba(0,0,0,.8);background-color:#000\9;filter:Alpha(opacity=80);color:#fff;overflow:hidden;font-size:0}.layui-layer-imgtit *{display:inline-block;*display:inline;*zoom:1;vertical-align:top;font-size:12px}.layui-layer-imgtit a{max-width:65%;overflow:hidden;color:#fff}.layui-layer-imgtit a:hover{color:#fff;text-decoration:underline}.layui-layer-imgtit em{padding-left:10px;font-style:normal} -------------------------------------------------------------------------------- /static/js/recommedBar.js: -------------------------------------------------------------------------------- 1 | var domCourse = document.getElementById("course_box"); 2 | var domPerson = document.getElementById("person_box"); 3 | var chartCourse = echarts.init(domCourse); 4 | var chartPerson = echarts.init(domPerson); 5 | var app = {}; 6 | optionCourse = null; 7 | optionPerson = null; 8 | $.getJSON('/getRecommedData', function(coursePersonJson) 9 | { 10 | var optionCourse = { 11 | dataset: coursePersonJson['course'], 12 | grid: {containLabel: true}, 13 | xAxis: {name: '喜爱程度'}, 14 | yAxis: {type: 'category'}, 15 | visualMap: { 16 | orient: 'horizontal', 17 | left: 'center', 18 | min: 1, 19 | max: 5, 20 | text: ['High Score', 'Low Score'], 21 | // Map the score column to color 22 | dimension: 0, 23 | inRange: { 24 | color: ['#D7DA8B', '#E15457'] 25 | } 26 | }, 27 | series: [ 28 | { 29 | type: 'bar', 30 | encode: { 31 | // Map the "amount" column to X axis. 32 | x: 'amount', 33 | // Map the "product" column to Y axis 34 | y: 'product' 35 | } 36 | } 37 | ] 38 | }; 39 | var optionPerson = { 40 | dataset: coursePersonJson['person'], 41 | grid: {containLabel: true}, 42 | xAxis: {name: '相似度'}, 43 | yAxis: {type: 'category'}, 44 | visualMap: { 45 | orient: 'horizontal', 46 | left: 'center', 47 | min: 0.7, 48 | max: 1, 49 | text: ['High Score', 'Low Score'], 50 | // Map the score column to color 51 | dimension: 0, 52 | inRange: { 53 | color: ['#D7DA8B', '#E15457'] 54 | } 55 | }, 56 | series: [ 57 | { 58 | type: 'bar', 59 | encode: { 60 | // Map the "amount" column to X axis. 61 | x: 'amount', 62 | // Map the "product" column to Y axis 63 | y: 'product' 64 | } 65 | } 66 | ] 67 | }; 68 | if (optionCourse && typeof optionCourse === "object") { 69 | chartCourse.setOption(optionCourse, true); 70 | } 71 | if (optionPerson && typeof optionPerson === "object") { 72 | chartPerson.setOption(optionPerson, true); 73 | } 74 | }); 75 | -------------------------------------------------------------------------------- /templates/404.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Page Not Found{% endblock %} 4 | 5 | {% block page_content %} 6 | 9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /templates/500.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Internal Server Error{% endblock %} 4 | 5 | {% block page_content %} 6 | 9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /templates/course_discussion.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 课程论坛 11 | 12 | 13 | 14 |
15 |
16 |
17 |
18 | 19 | 20 | 36 |
37 | 49 |
50 | 51 | 62 | 77 | 78 | 79 | 80 | 81 |
82 |
83 | 90 |
91 |
92 |

发布话题

93 |
94 | 首页> 95 | 课程论坛 > 96 | 发布话题 97 |
98 |
99 | 100 |
101 |
102 | 103 | 104 | 105 |
话题:
内容:
106 |
107 |
108 | 109 |
110 |
111 | 112 | 113 |
114 | 115 | 116 | -------------------------------------------------------------------------------- /templates/detail.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 评论回复 12 | 13 | 175 | 176 | 177 |
178 |
179 |
180 |
181 | 182 | 183 | 199 |
200 | 212 |
213 | 214 | 225 | 240 | 241 | 242 | 243 | 244 | 245 |
246 |
247 | 248 | 249 | 254 |
250 |
251 | 252 |
253 |
255 |
256 |
257 | 258 | 259 | 260 |
261 |
262 | 263 | 264 | 265 | 266 |
267 |

{{ title[0] }}

268 |
269 | {{ title[2] }} 发表 270 | {{ title[3] }} 271 |
272 |
273 |
274 |

{{ title[1] }}

275 |
276 |
277 | {% for message in result %} 278 |

  • {{ message[2] }}:【 {{ message[0] }}】 {{ message[1] }}{{ message[3] }}
  • 279 |

    280 |
    281 | {% endfor %} 282 | 283 | 284 | 285 | 286 | -------------------------------------------------------------------------------- /templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 首页 11 | 12 | 13 | 14 |
    15 |
    16 |
    17 |
    18 | 19 | 33 |
    34 | 46 |
    47 | 48 | 59 | 74 | 75 | 76 | 77 | 78 |
    79 |
      80 |
    • 81 | 82 |

      课程进度

      83 |
    • 84 |
    • 85 | 86 |

      选课推荐

      87 |
    • 88 |
    • 89 | 90 |

      课程讨论

      91 |
    • 92 |
    • 93 | 94 |

      个人中心

      95 |
    • 96 |
    97 |
    98 | 99 | 100 | 101 |
    102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /templates/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 登录 6 | 7 | 8 | 9 | 10 |
    11 |
    12 |
    13 |

    天津大学

    14 |

    本科培养计划

    15 |
    16 | 17 |
    18 |
    19 |
    20 | 登录 21 | 修改密码 22 |
    23 |
    24 |
    25 |
    26 | 40 |
    41 | 42 |
    43 | 44 | 47 |
    48 |
    49 |
    50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 68 | 69 | -------------------------------------------------------------------------------- /templates/manager.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 管理界面 6 | 7 | 8 | 19 | 20 | 21 |
    管理界面
    22 |
    23 | 24 | 25 | {% for message in result %} 26 | 27 | {% endfor %} 28 |
    NAMESEXSTU_NOCOLLEGEMAJORAD_YEARPASSWORDID
    {{ message[0] }}{{ message[1] }}{{ message[2] }}{{ message[3] }}{{ message[4] }}{{ message[5] }}{{ message[6] }}{{ message[7] }}
    29 |
    30 |
    31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 |
    39 |
    40 |
    41 | 42 | -------------------------------------------------------------------------------- /templates/managerAdd.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 添加用户 6 | 7 | 8 | 9 | 10 |
    11 |
    12 | 40 |
    41 | 42 | 43 | -------------------------------------------------------------------------------- /templates/managerDelete.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 删除用户 6 | 7 | 8 | 9 | 10 |
    11 |
    12 | 22 |
    23 | 24 | 25 | -------------------------------------------------------------------------------- /templates/managerEdit.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 编辑用户 6 | 7 | 8 | 9 | 10 |
    11 |
    12 | 43 |
    44 | 45 | 46 | -------------------------------------------------------------------------------- /templates/news_center.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 课程论坛 12 | 13 | 14 | 15 |
    16 |
    17 |
    18 |
    19 | 20 | 34 |
    35 | 47 |
    48 | 49 | 60 | 75 | 76 | 77 | 78 | 79 |
    80 |
    81 | 88 |
    89 |
    90 |

    课程讨论

    91 | 92 |
    93 |
    94 | 99 |
    100 | 101 |
    102 |
    103 | 104 | 105 |
    106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /templates/personal_information.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 个人中心 12 | 13 | 14 | 15 |
    16 |
    17 |
    18 |
    19 | 20 | 34 |
    35 | 47 |
    48 | 49 | 62 | 84 | 85 | 86 | 87 | 88 |
    89 |
    90 | 98 |
    99 |
    100 |

    个人信息

    101 |
    102 | 首页 > 103 | 个人中心 > 104 | 个人信息 105 |
    106 |
    107 |
    108 |

    姓名:{{ result[0][0] }}

    109 |

    学号:{{ result[0][2] }}

    110 |

    学院:{{ result[0][3] }}

    111 |

    专业:{{ result[0][4] }}

    112 | 113 |
    114 | 122 |
    123 |
    124 | 125 |
    126 |
    127 |
    128 | 129 | 130 |
    131 | 132 | -------------------------------------------------------------------------------- /templates/recommed.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 选课推荐 31 | 32 | 33 |
    34 |
    35 |
    36 |
    37 | 38 | 52 |
    53 | 64 |
    65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 |
    77 | 78 |
    79 |
    80 |

    您可能喜欢的课程

    81 |
    82 |
    83 |
    84 |
    85 |
    86 |

    可能和您志同道和的朋友

    87 |
    88 |
    89 |
    90 | 91 | 92 | -------------------------------------------------------------------------------- /templates/register.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 注册 6 | 7 | 8 | 9 | 10 |
    11 |
    12 |
    13 |

    天津大学

    14 |

    本科培养计划

    15 |
    16 | 17 |
    18 |
    19 |
    20 | 登录 21 | 修改密码 22 |
    23 |
    24 |
    25 |
    26 | 46 |
    47 | 48 |
    49 |
    50 | 51 | 52 | 53 | 54 | 55 | 56 | 89 | 90 | -------------------------------------------------------------------------------- /templates/train_plan.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 培养计划 29 | 30 |
    31 |
    32 |
    33 |
    34 | 35 | 49 |
    50 | 61 |
    62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 |
    74 | 75 |
    76 |
      77 |
      78 |

      课程进度

      评分

      79 | 80 |
      81 |
        82 |

        总进度

        83 |
        84 |

        0%

        85 |
        86 |
        87 |
        88 |
        89 |

        思想政治

        90 |
        91 |

        0%

        92 |
        93 |
        94 |
        95 |
        96 |

        外语

        97 |
        98 |

        0%

        99 |
        100 |
        101 |
        102 |
        103 |

        文化素质

        104 |
        105 |

        0%

        106 |
        107 |
        108 |
        109 |
        110 |

        体育

        111 |
        112 |

        0%

        113 |
        114 |
        115 |
        116 |
        117 |

        军事

        118 |
        119 |

        0%

        120 |
        121 |
        122 |
        123 |
        124 |

        健康教育

        125 |
        126 |

        0%

        127 |
        128 |
        129 |
        130 |
        131 |

        数学

        132 |
        133 |

        0%

        134 |
        135 |
        136 |
        137 |
        138 |

        物理

        139 |
        140 |

        0%

        141 |
        142 |
        143 |
        144 |
        145 |

        计算机

        146 |
        147 |

        0%

        148 |
        149 |
        150 |
        151 |
        152 |

        学科基础

        153 |
        154 |

        0%

        155 |
        156 |
        157 |
        158 |
        159 |

        专业选修

        160 |
        161 |

        0%

        162 |
        163 |
        164 |
        165 |
        166 |
        167 | 168 |
        169 |
        170 | 171 |
        172 |
      173 |
      174 | 175 |
        176 | 179 |

        180 | 183 |

        184 | 187 |

        188 |
        189 | 190 |
        191 |
      192 | 193 | 202 | 207 | 208 |
      209 |
    210 |
    211 | 212 | 213 |
    214 | 215 | 216 | -------------------------------------------------------------------------------- /utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiefan-guo/studentTrainPlan/daf74215a6c683cb4f48d096d338a52d75f8a1fb/utils/__init__.py -------------------------------------------------------------------------------- /utils/__pycache__/__init__.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiefan-guo/studentTrainPlan/daf74215a6c683cb4f48d096d338a52d75f8a1fb/utils/__pycache__/__init__.cpython-36.pyc -------------------------------------------------------------------------------- /utils/__pycache__/__init__.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiefan-guo/studentTrainPlan/daf74215a6c683cb4f48d096d338a52d75f8a1fb/utils/__pycache__/__init__.cpython-37.pyc -------------------------------------------------------------------------------- /utils/__pycache__/config.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiefan-guo/studentTrainPlan/daf74215a6c683cb4f48d096d338a52d75f8a1fb/utils/__pycache__/config.cpython-36.pyc -------------------------------------------------------------------------------- /utils/__pycache__/config.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiefan-guo/studentTrainPlan/daf74215a6c683cb4f48d096d338a52d75f8a1fb/utils/__pycache__/config.cpython-37.pyc -------------------------------------------------------------------------------- /utils/__pycache__/map_student_course.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiefan-guo/studentTrainPlan/daf74215a6c683cb4f48d096d338a52d75f8a1fb/utils/__pycache__/map_student_course.cpython-36.pyc -------------------------------------------------------------------------------- /utils/__pycache__/map_student_course.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiefan-guo/studentTrainPlan/daf74215a6c683cb4f48d096d338a52d75f8a1fb/utils/__pycache__/map_student_course.cpython-37.pyc -------------------------------------------------------------------------------- /utils/__pycache__/query.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiefan-guo/studentTrainPlan/daf74215a6c683cb4f48d096d338a52d75f8a1fb/utils/__pycache__/query.cpython-36.pyc -------------------------------------------------------------------------------- /utils/__pycache__/query.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiefan-guo/studentTrainPlan/daf74215a6c683cb4f48d096d338a52d75f8a1fb/utils/__pycache__/query.cpython-37.pyc -------------------------------------------------------------------------------- /utils/__pycache__/recommed_module.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiefan-guo/studentTrainPlan/daf74215a6c683cb4f48d096d338a52d75f8a1fb/utils/__pycache__/recommed_module.cpython-36.pyc -------------------------------------------------------------------------------- /utils/__pycache__/recommed_module.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiefan-guo/studentTrainPlan/daf74215a6c683cb4f48d096d338a52d75f8a1fb/utils/__pycache__/recommed_module.cpython-37.pyc -------------------------------------------------------------------------------- /utils/map_student_course.py: -------------------------------------------------------------------------------- 1 | from utils.query import query 2 | 3 | def get_map_student(): 4 | map_student = {} 5 | stuNo2MatNo = {} 6 | sql = "SELECT NAME, STU_NO FROM STUDENT WHERE STU_NO<>'admin'" 7 | result = query(sql) 8 | map_student_id = 0 9 | for cur in result: 10 | values = list(cur) 11 | map_student[map_student_id] = values 12 | map_student_id = map_student_id + 1 13 | 14 | map_course = {} 15 | sql="SELECT CO_NAME FROM EDUCATION_PLAN" 16 | result = query(sql) 17 | map_course_id = 0 18 | for cur in result: 19 | map_course[map_course_id] = cur[0] 20 | map_course_id = map_course_id + 1 21 | 22 | for idx in range(len(map_student)): 23 | stuNo2MatNo[map_student[idx][1]] = idx 24 | return map_student, map_course, stuNo2MatNo 25 | 26 | 27 | def get_matrix(map_student): 28 | matrix = [] 29 | for i in range(30): 30 | matrix.append([]) 31 | for i in range(30): 32 | stu_no = map_student[i][1] 33 | #print(stu_no) 34 | sql="SELECT COMMENT FROM CHOOSE WHERE STU_NO='%s'" % (stu_no) 35 | score=query(sql) 36 | #print(score) 37 | for j in range(118): 38 | matrix[i].append(int(score[j][0])) 39 | 40 | return matrix 41 | 42 | -------------------------------------------------------------------------------- /utils/query.py: -------------------------------------------------------------------------------- 1 | import pymysql 2 | from config import config 3 | 4 | def query(sql): 5 | """ 6 | 功能; 使用sql语句查询数据库中学生选课信息. 7 | 参数: sql(string) 8 | """ 9 | db = pymysql.connect('localhost', 'root', config['MYSQL_PASSWORD'], config['DATABASE_NAME'], charset='utf8') 10 | cur = db.cursor() 11 | try: 12 | cur.execute(sql) 13 | result = cur.fetchall() 14 | db.commit() 15 | 16 | #print('query success') 17 | 18 | # print('query success') 19 | except: 20 | # print('query loss') 21 | db.rollback() 22 | cur.close() 23 | db.close() 24 | return result 25 | 26 | 27 | def update(sql): 28 | """ 29 | 功能; 使用sql语句更新数据库中学生选课信息。 30 | 参数: sql(string) 31 | """ 32 | db = pymysql.connect('localhost', 'root', config['MYSQL_PASSWORD'], config['DATABASE_NAME'], charset='utf8') 33 | cur = db.cursor() 34 | try: 35 | cur.execute(sql) 36 | db.commit() 37 | #print('update success') 38 | # print('update success') 39 | except: 40 | # print('update loss') 41 | db.rollback() 42 | cur.close() 43 | db.close() 44 | 45 | def getPlanTreeJson(stu_id): 46 | """ 47 | 功能: 传入学生stu_id,然后利用stu_id从数据库查询得到该学生选课信息,再转换为计划树所需的json格式 48 | :param stu_id: 唯一标识学生的id号 49 | :return: 学生选课计划树Json数据 50 | """ 51 | print(stu_id) 52 | sql = "select FINISHED_CO from EDU_STU_PLAN WHERE STU_NO='%s'" % stu_id 53 | result = query(sql) 54 | print(result) 55 | finished_co = result[0][0] 56 | print(finished_co) 57 | 58 | data = {} 59 | data['name'] = '总进度' 60 | children = [] 61 | 62 | children1 = {} 63 | children1['name'] = '思想政治理论' 64 | children1_list =[] 65 | children2 = {} 66 | children2['name'] = '外语' 67 | children2_list = [] 68 | children3 = {} 69 | children3['name'] = '文化素质教育必修' 70 | children3_list = [] 71 | children4 = {} 72 | children4['name'] = '体育' 73 | children4_list = [] 74 | children5 = {} 75 | children5['name'] = '军事' 76 | children5_list = [] 77 | children6 = {} 78 | children6['name'] = '健康教育' 79 | children6_list = [] 80 | children7 = {} 81 | children7['name'] = '数学' 82 | children7_list = [] 83 | children8 = {} 84 | children8['name'] = '物理' 85 | children8_list = [] 86 | children9 = {} 87 | children9['name'] = '计算机' 88 | children9_list = [] 89 | children10 = {} 90 | children10['name'] = '学科基础' 91 | children10_list = [] 92 | children11 = {} 93 | children11['name'] = '专业选修' 94 | children11_list = [] 95 | aid = 1 96 | 97 | score = [0.0] * 15 98 | 99 | add_time_list = [] 100 | for j in range(44): 101 | add_time_list.append([]) 102 | 103 | sql="SELECT CO_NO,COMMENT FROM CHOOSE WHERE STU_NO='%s'" % stu_id 104 | course2score=query(sql) 105 | co2score = {} 106 | for cur in course2score: 107 | co2score[cur[0]] = cur[1] 108 | 109 | #print(co2score) 110 | 111 | for co in finished_co: 112 | course_add = {} 113 | aid_str = str(aid) 114 | sql = "select CLASSIFICATION, START_TIME, CO_NAME, IS_MUST, CREDITS, CO_NO from education_plan WHERE CO_100='%s'" % aid_str 115 | co_name = query(sql) 116 | #print('数据库查询结果') 117 | #print(co_name) 118 | aid = aid + 1 119 | add_is_list = [] 120 | 121 | add_curse = {} 122 | add_is = {} 123 | 124 | add_score = float(co_name[0][4]) 125 | 126 | if co == '0': 127 | #print(co_name) 128 | add_curse['name'] = co_name[0][2] 129 | add_curse['itemStyle'] = {'borderColor': 'red'} 130 | add_curse['value'] = add_score 131 | add_curse['score'] = int(co2score[co_name[0][5]]) 132 | 133 | if co_name[0][3] == 1: 134 | add_is['name'] = '必修' 135 | else: 136 | add_is['name'] = '选修' 137 | 138 | add_is_list.append(add_curse) 139 | add_is['children'] = add_is_list 140 | # add_time['name'] = str(co_name[0][1]) 141 | # add_time_list.append(add_is) 142 | # add_time['children'] = add_time_list 143 | else: 144 | add_curse['name'] = co_name[0][2] 145 | add_curse['itemStyle'] = {'borderColor': 'green'} 146 | add_curse['value'] = add_score 147 | add_curse['score'] = int(co2score[co_name[0][5]]) 148 | 149 | if co_name[0][3] == 1: 150 | add_is['name'] = '必修' 151 | else: 152 | add_is['name'] = '选修' 153 | 154 | add_is_list.append(add_curse) 155 | add_is['children'] = add_is_list 156 | # add_time['name'] = str(co_name[0][1]) 157 | # add_time_list.append(add_is) 158 | # add_time['children'] = add_time_list 159 | 160 | str_co_time = str(co_name[0][1]) 161 | if co_name[0][0] == '思想政治理论': 162 | if str_co_time[3] == '6': 163 | add_time_list[0].append(add_is) 164 | if str_co_time[3] == '7': 165 | add_time_list[1].append(add_is) 166 | if str_co_time[3] == '8': 167 | add_time_list[2].append(add_is) 168 | if str_co_time[3] == '9': 169 | add_time_list[3].append(add_is) 170 | if co_name[0][0] == '外语': 171 | if str_co_time[3] == '6': 172 | add_time_list[4].append(add_is) 173 | if str_co_time[3] == '7': 174 | add_time_list[5].append(add_is) 175 | if str_co_time[3] == '8': 176 | add_time_list[6].append(add_is) 177 | if str_co_time[3] == '9': 178 | add_time_list[7].append(add_is) 179 | if co_name[0][0] == '文化素质教育必修': 180 | if str_co_time[3] == '6': 181 | add_time_list[8].append(add_is) 182 | if str_co_time[3] == '7': 183 | add_time_list[9].append(add_is) 184 | if str_co_time[3] == '8': 185 | add_time_list[10].append(add_is) 186 | if str_co_time[3] == '9': 187 | add_time_list[11].append(add_is) 188 | if co_name[0][0] == '体育': 189 | if str_co_time[3] == '6': 190 | add_time_list[12].append(add_is) 191 | if str_co_time[3] == '7': 192 | add_time_list[13].append(add_is) 193 | if str_co_time[3] == '8': 194 | add_time_list[14].append(add_is) 195 | if str_co_time[3] == '9': 196 | add_time_list[15].append(add_is) 197 | if co_name[0][0] == '军事': 198 | if str_co_time[3] == '6': 199 | add_time_list[16].append(add_is) 200 | if str_co_time[3] == '7': 201 | add_time_list[17].append(add_is) 202 | if str_co_time[3] == '8': 203 | add_time_list[18].append(add_is) 204 | if str_co_time[3] == '9': 205 | add_time_list[19].append(add_is) 206 | if co_name[0][0] == '健康教育': 207 | if str_co_time[3] == '6': 208 | add_time_list[20].append(add_is) 209 | if str_co_time[3] == '7': 210 | add_time_list[21].append(add_is) 211 | if str_co_time[3] == '8': 212 | add_time_list[22].append(add_is) 213 | if str_co_time[3] == '9': 214 | add_time_list[23].append(add_is) 215 | if co_name[0][0] == '数学': 216 | if str_co_time[3] == '6': 217 | add_time_list[24].append(add_is) 218 | if str_co_time[3] == '7': 219 | add_time_list[25].append(add_is) 220 | if str_co_time[3] == '8': 221 | add_time_list[26].append(add_is) 222 | if str_co_time[3] == '9': 223 | add_time_list[27].append(add_is) 224 | if co_name[0][0] == '物理': 225 | if str_co_time[3] == '6': 226 | add_time_list[28].append(add_is) 227 | if str_co_time[3] == '7': 228 | add_time_list[29].append(add_is) 229 | if str_co_time[3] == '8': 230 | add_time_list[30].append(add_is) 231 | if str_co_time[3] == '9': 232 | add_time_list[31].append(add_is) 233 | if co_name[0][0] == '计算机': 234 | if str_co_time[3] == '6': 235 | add_time_list[32].append(add_is) 236 | if str_co_time[3] == '7': 237 | add_time_list[33].append(add_is) 238 | if str_co_time[3] == '8': 239 | add_time_list[34].append(add_is) 240 | if str_co_time[3] == '9': 241 | add_time_list[35].append(add_is) 242 | if co_name[0][0] == '学科基础': 243 | if str_co_time[3] == '6': 244 | add_time_list[36].append(add_is) 245 | if str_co_time[3] == '7': 246 | add_time_list[37].append(add_is) 247 | if str_co_time[3] == '8': 248 | add_time_list[38].append(add_is) 249 | if str_co_time[3] == '9': 250 | add_time_list[39].append(add_is) 251 | if co_name[0][0] == '专业选修': 252 | if str_co_time[3] == '6': 253 | add_time_list[40].append(add_is) 254 | if str_co_time[3] == '7': 255 | add_time_list[41].append(add_is) 256 | if str_co_time[3] == '8': 257 | add_time_list[42].append(add_is) 258 | if str_co_time[3] == '9': 259 | add_time_list[43].append(add_is) 260 | 261 | add_time = {} 262 | add_time['name'] = '2016' 263 | add_time['children'] = add_time_list[0] 264 | children1_list.append(add_time) 265 | add_time = {} 266 | add_time['name'] = '2017' 267 | add_time['children'] = add_time_list[1] 268 | children1_list.append(add_time) 269 | add_time = {} 270 | add_time['name'] = '2018' 271 | add_time['children'] = add_time_list[2] 272 | children1_list.append(add_time) 273 | add_time = {} 274 | add_time['name'] = '2019' 275 | add_time['children'] = add_time_list[3] 276 | children1_list.append(add_time) 277 | 278 | add_time = {} 279 | add_time['name'] = '2016' 280 | add_time['children'] = add_time_list[4] 281 | children2_list.append(add_time) 282 | add_time = {} 283 | add_time['name'] = '2017' 284 | add_time['children'] = add_time_list[5] 285 | children2_list.append(add_time) 286 | add_time = {} 287 | add_time['name'] = '2018' 288 | add_time['children'] = add_time_list[6] 289 | children2_list.append(add_time) 290 | add_time = {} 291 | add_time['name'] = '2019' 292 | add_time['children'] = add_time_list[7] 293 | children2_list.append(add_time) 294 | 295 | add_time = {} 296 | add_time['name'] = '2016' 297 | add_time['children'] = add_time_list[8] 298 | children3_list.append(add_time) 299 | add_time = {} 300 | add_time['name'] = '2017' 301 | add_time['children'] = add_time_list[9] 302 | children3_list.append(add_time) 303 | add_time = {} 304 | add_time['name'] = '2018' 305 | add_time['children'] = add_time_list[10] 306 | children3_list.append(add_time) 307 | add_time = {} 308 | add_time['name'] = '2019' 309 | add_time['children'] = add_time_list[11] 310 | children3_list.append(add_time) 311 | 312 | add_time = {} 313 | add_time['name'] = '2016' 314 | add_time['children'] = add_time_list[12] 315 | children4_list.append(add_time) 316 | add_time = {} 317 | add_time['name'] = '2017' 318 | add_time['children'] = add_time_list[13] 319 | children4_list.append(add_time) 320 | add_time = {} 321 | add_time['name'] = '2018' 322 | add_time['children'] = add_time_list[14] 323 | children4_list.append(add_time) 324 | add_time = {} 325 | add_time['name'] = '2019' 326 | add_time['children'] = add_time_list[15] 327 | children4_list.append(add_time) 328 | 329 | add_time = {} 330 | add_time['name'] = '2016' 331 | add_time['children'] = add_time_list[16] 332 | children5_list.append(add_time) 333 | add_time = {} 334 | add_time['name'] = '2017' 335 | add_time['children'] = add_time_list[17] 336 | children5_list.append(add_time) 337 | add_time = {} 338 | add_time['name'] = '2018' 339 | add_time['children'] = add_time_list[18] 340 | children5_list.append(add_time) 341 | add_time = {} 342 | add_time['name'] = '2019' 343 | add_time['children'] = add_time_list[19] 344 | children5_list.append(add_time) 345 | 346 | add_time = {} 347 | add_time['name'] = '2016' 348 | add_time['children'] = add_time_list[20] 349 | children6_list.append(add_time) 350 | add_time = {} 351 | add_time['name'] = '2017' 352 | add_time['children'] = add_time_list[21] 353 | children6_list.append(add_time) 354 | add_time = {} 355 | add_time['name'] = '2018' 356 | add_time['children'] = add_time_list[22] 357 | children6_list.append(add_time) 358 | add_time = {} 359 | add_time['name'] = '2019' 360 | add_time['children'] = add_time_list[23] 361 | children6_list.append(add_time) 362 | 363 | add_time = {} 364 | add_time['name'] = '2016' 365 | add_time['children'] = add_time_list[24] 366 | children7_list.append(add_time) 367 | add_time = {} 368 | add_time['name'] = '2017' 369 | add_time['children'] = add_time_list[25] 370 | children7_list.append(add_time) 371 | add_time = {} 372 | add_time['name'] = '2018' 373 | add_time['children'] = add_time_list[26] 374 | children7_list.append(add_time) 375 | add_time = {} 376 | add_time['name'] = '2019' 377 | add_time['children'] = add_time_list[27] 378 | children7_list.append(add_time) 379 | 380 | add_time = {} 381 | add_time['name'] = '2016' 382 | add_time['children'] = add_time_list[28] 383 | children8_list.append(add_time) 384 | add_time = {} 385 | add_time['name'] = '2017' 386 | add_time['children'] = add_time_list[29] 387 | children8_list.append(add_time) 388 | add_time = {} 389 | add_time['name'] = '2018' 390 | add_time['children'] = add_time_list[30] 391 | children8_list.append(add_time) 392 | add_time = {} 393 | add_time['name'] = '2019' 394 | add_time['children'] = add_time_list[31] 395 | children8_list.append(add_time) 396 | 397 | add_time = {} 398 | add_time['name'] = '2016' 399 | add_time['children'] = add_time_list[32] 400 | children9_list.append(add_time) 401 | add_time = {} 402 | add_time['name'] = '2017' 403 | add_time['children'] = add_time_list[33] 404 | children9_list.append(add_time) 405 | add_time = {} 406 | add_time['name'] = '2018' 407 | add_time['children'] = add_time_list[34] 408 | children9_list.append(add_time) 409 | add_time = {} 410 | add_time['name'] = '2019' 411 | add_time['children'] = add_time_list[35] 412 | children9_list.append(add_time) 413 | 414 | add_time = {} 415 | add_time['name'] = '2016' 416 | add_time['children'] = add_time_list[36] 417 | children10_list.append(add_time) 418 | add_time = {} 419 | add_time['name'] = '2017' 420 | add_time['children'] = add_time_list[37] 421 | children10_list.append(add_time) 422 | add_time = {} 423 | add_time['name'] = '2018' 424 | add_time['children'] = add_time_list[38] 425 | children10_list.append(add_time) 426 | add_time = {} 427 | add_time['name'] = '2019' 428 | add_time['children'] = add_time_list[39] 429 | children10_list.append(add_time) 430 | 431 | add_time = {} 432 | add_time['name'] = '2016' 433 | add_time['children'] = add_time_list[40] 434 | children11_list.append(add_time) 435 | add_time = {} 436 | add_time['name'] = '2017' 437 | add_time['children'] = add_time_list[41] 438 | children11_list.append(add_time) 439 | add_time = {} 440 | add_time['name'] = '2018' 441 | add_time['children'] = add_time_list[42] 442 | children11_list.append(add_time) 443 | add_time = {} 444 | add_time['name'] = '2019' 445 | add_time['children'] = add_time_list[43] 446 | children11_list.append(add_time) 447 | 448 | children1['value'] = 16 449 | children2['value'] = 8 450 | children3['value'] = 5.5 451 | children4['value'] = 4 452 | children5['value'] = 5 453 | children6['value'] = 0.5 454 | children7['value'] = 21.5 455 | children8['value'] = 9 456 | children9['value'] = 4.0 457 | children10['value'] = 24.5 458 | children11['value'] = 21.5 459 | 460 | children1['children'] = children1_list 461 | children2['children'] = children2_list 462 | children3['children'] = children3_list 463 | children4['children'] = children4_list 464 | children5['children'] = children5_list 465 | children6['children'] = children6_list 466 | children7['children'] = children7_list 467 | children8['children'] = children8_list 468 | children9['children'] = children9_list 469 | children10['children'] = children10_list 470 | children11['children'] = children11_list 471 | 472 | children.append(children1) 473 | children.append(children2) 474 | children.append(children3) 475 | children.append(children4) 476 | children.append(children5) 477 | children.append(children6) 478 | children.append(children7) 479 | children.append(children8) 480 | children.append(children9) 481 | children.append(children10) 482 | children.append(children11) 483 | data['children'] = children 484 | return data 485 | 486 | def updateDatabase(stu_id, train_plan): 487 | """ 488 | 功能: 用户在“培养计划”界面点击“提交”按钮后,使用最新“计划树”信息更新数据库 489 | :param stu_id: 唯一标识学生的id 490 | :param train_plan: “培养计划”界面“计划树”数据的json格式 491 | :return: 无 492 | """ 493 | data = train_plan['children'] 494 | array_finish = [0]*120 495 | # print(array_finish) 496 | for data_children in data: 497 | data_children = data_children['children'] 498 | print(data_children) 499 | for data_children_child_1 in data_children: 500 | # print('data_children_child', data_children_child) 501 | data_children_child_1 = data_children_child_1['children'] 502 | for data_children_child in data_children_child_1: 503 | name = data_children_child['children'][0]['name'] 504 | color = data_children_child['children'][0]['itemStyle']['borderColor'] 505 | #print(name, color) 506 | sql = "select CO_100 from education_plan WHERE CO_NAME='%s'" % name 507 | co_100 = query(sql) 508 | co_100 = co_100[0][0] 509 | 510 | if color == 'red': 511 | array_finish[int(co_100)] = 0 512 | else: 513 | array_finish[int(co_100)] = 1 514 | finish_co = '' 515 | for i in range(1, 119): 516 | if array_finish[i] == 1: 517 | finish_co += '1' 518 | else: 519 | finish_co += '0' 520 | print(finish_co) 521 | #print(array_finish) 522 | sql = "UPDATE edu_stu_plan SET FINISHED_CO='%s' WHERE STU_NO='%s'" % (finish_co,stu_id) 523 | update(sql) 524 | 525 | 526 | def updateScore(stu_id, scores): 527 | sql="SELECT CO_NO, CO_NAME FROM EDUCATION_PLAN"; 528 | name2no = {} 529 | result = query(sql) 530 | for cur in result: 531 | name2no[cur[1]] = cur[0] 532 | 533 | for cur in scores: 534 | sql="UPDATE CHOOSE SET COMMENT='%d' WHERE STU_NO='%s' AND CO_NO='%s'" % (scores[cur], stu_id, name2no[cur]) 535 | #print(sql) 536 | update(sql) -------------------------------------------------------------------------------- /utils/recommed_module.py: -------------------------------------------------------------------------------- 1 | # 相似性度量函数, 输入列向量, 归一化 0-1 2 | from numpy import * 3 | import numpy as np 4 | from numpy import linalg as la 5 | 6 | def getSigK(Sigma, k): 7 | ''' 8 | 输入: 9 | Sigma: 输入的奇异值向量 10 | k: 取前几个奇异值 11 | 输出:(k,k)的矩阵 12 | ''' 13 | eyeK = np.eye(k) 14 | return mat(eyeK * Sigma[:k]) 15 | def reBuild(U, Sigma, VT, k): 16 | ''' 17 | 使用前k个特征值重构数据 18 | ''' 19 | Sigk = getSigK(Sigma, k) 20 | # 左行右列 21 | return mat(np.dot(np.dot(U[:,:k], Sigk), VT[: k,:])) 22 | 23 | def ecludSim(inA,inB): 24 | return 1.0/(1.0 + la.norm(inA - inB)) 25 | 26 | def cosSim(inA, inB): 27 | ''' 28 | 基于余弦相似性度量 29 | ''' 30 | sim = float(inA.T* inB) / (la.norm(inA) * la.norm(inB)) 31 | return 0.5 + 0.5 * sim 32 | 33 | def svdMethod(svdData, dataMat, simMeas, user, item): 34 | ''' 35 | 输入: 36 | 见recommend函数 37 | 输出: 38 | Score(double): user对item的评分 39 | 算法流程: 40 | 1. for item_other in allItem 41 | 2. if haveBeenScore(item_other) 42 | 3. compute_Simliar_Score(item, item_other) 43 | 4. return Score 44 | ''' 45 | N = shape(dataMat)[1] 46 | simTotal = 0.0 47 | ratSimTotal = 0.0 48 | U, Sigma, I_t = svdData 49 | k = 0 50 | while sum(Sigma[:k]) < sum(Sigma) * 0.9: 51 | k = k+ 1 52 | SigK = getSigK(Sigma, k) 53 | itemFeature = dataMat.T * U[:,:k] * SigK.I 54 | for j in range(N): 55 | if dataMat[user,j] == 0 or j == item: 56 | continue 57 | sim = simMeas(itemFeature[item,:].T, itemFeature[j,:].T) 58 | # print("the similarity between {} and {} is {}".format(j,item, sim)) 59 | ratSim = dataMat[user, j] * sim 60 | simTotal += sim 61 | ratSimTotal += ratSim 62 | if simTotal == 0: 63 | return 0 64 | return ratSimTotal / simTotal 65 | 66 | def recommedCoursePerson(dataMat, user, N=7, simMeas=ecludSim, estMethod=svdMethod): 67 | ''' 68 | 输入: 69 | dataMat(mat)(M,N): 评分矩阵. 70 | use(int): 想推荐的用户id. 71 | N(int): 为用户推荐的未评分的商品个数 72 | simMeas(double): 两个特征向量的相似度评价函数 73 | estMethod(double):推荐核心方法,计算商品对于用户的分数的函数 74 | 输出: 75 | N * (item, 评分): N个商品以及其的评分 76 | 算法流程: 77 | 1. 找到所有未评分的商品 78 | 2. 若没有未评分商品,退出 79 | 3. 遍历未评分商品. 80 | 4. 计算用户可能对该商品的评分 81 | 5. 排序取前N个输出. 82 | ''' 83 | print(user) 84 | dataMat = mat(dataMat) 85 | unRatedItems = nonzero(dataMat[user,:].A == 0)[1] 86 | if len(unRatedItems) == 0: 87 | print("没有未评分商品") 88 | return None 89 | U, Sigma, I_t = la.svd(dataMat) 90 | item_and_score = [] 91 | for item in unRatedItems: 92 | score = estMethod([U, Sigma, I_t], dataMat, simMeas, user, item) 93 | item_and_score.append((item, score)) 94 | 95 | k = 0 96 | while sum(Sigma[:k]) < sum(Sigma) * 0.9: 97 | k = k+ 1 98 | SigK = getSigK(Sigma, k) 99 | userFeature = dataMat * I_t[:,:k] * SigK.I 100 | recomedUserVec = userFeature[user,:] 101 | user_and_score = [] 102 | for idx, each in enumerate(userFeature): 103 | if user != idx: 104 | user_and_score.append((idx, cosSim(recomedUserVec.T, each.T))) 105 | recommedCourse = sorted(item_and_score, key=lambda k: k[1], reverse=True)[:min(N, len(item_and_score))] 106 | recommedPerson = sorted(user_and_score, key=lambda k: k[1], reverse=True)[:min(N, len(user_and_score))] 107 | print(recommedCourse) 108 | print(recommedPerson) 109 | return recommedCourse, recommedPerson 110 | 111 | 112 | def toBarJson(data, dict2id): 113 | """ 114 | 115 | :param data: [(0, 5.0), (1, 5.0), (2, 5.0)] 116 | :return:: 117 | { 118 | "source": [ 119 | [2.3, "计算机视觉"], 120 | [1.1, "自然语言处理"], 121 | [2.4, "高等数学"], 122 | [3.1, "线性代数"], 123 | [4.7, "计算机网络"], 124 | [5.1, "离散数学"] 125 | ] 126 | } 127 | """ 128 | jsonData = {"source":[]} 129 | for each in data: 130 | unit = [each[1], dict2id[each[0]]] 131 | jsonData['source'].append(unit) 132 | return jsonData 133 | 134 | def regularData(data, a, b): 135 | """ 136 | 功能,将列表的值归一化到[a,b]之间 137 | """ 138 | dataNum = [i[0] for i in data['source']] 139 | Max, Min = max(dataNum), min(dataNum) 140 | k = (b-a)/(Max-Min) 141 | dataRg = [a+ k*(i-Min) for i in dataNum] 142 | for idx,each in enumerate(data['source']): 143 | each[0] = dataRg[idx] 144 | return data -------------------------------------------------------------------------------- /utils/resource.py: -------------------------------------------------------------------------------- 1 | data = {} 2 | data['name'] = '总进度' 3 | children = [] 4 | 5 | children1 = {} 6 | children1['name'] = '思想政治理论' 7 | 8 | children2 = {} 9 | children1['name'] = '外语' 10 | 11 | children3 = {} 12 | children1['name'] = '文化素质教育必修' 13 | 14 | children4 = {} 15 | children1['name'] = '体育' 16 | 17 | children5 = {} 18 | children1['name'] = '军事' 19 | 20 | children6 = {} 21 | children1['name'] = '健康教育' 22 | 23 | children7 = {} 24 | children1['name'] = '数学' 25 | 26 | children8 = {} 27 | children1['name'] = '物理' 28 | 29 | children9 = {} 30 | children1['name'] = '计算机' 31 | 32 | children10 = {} 33 | children1['name'] = '学科基础' 34 | 35 | children11 = {} 36 | children1['name'] = '专业选修' 37 | 38 | children.append(children1) 39 | children.append(children2) 40 | children.append(children3) 41 | children.append(children4) 42 | children.append(children5) 43 | children.append(children6) 44 | children.append(children7) 45 | children.append(children8) 46 | children.append(children9) 47 | children.append(children10) 48 | children.append(children11) 49 | 50 | -------------------------------------------------------------------------------- /utils/toJson.py: -------------------------------------------------------------------------------- 1 | 2 | def toJson(data, length): 3 | json = [] 4 | for row in data: 5 | res ={} 6 | res['value'] = row[0] 7 | json.append(res) 8 | 9 | return json -------------------------------------------------------------------------------- /学生培养计划管理系统说明书.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiefan-guo/studentTrainPlan/daf74215a6c683cb4f48d096d338a52d75f8a1fb/学生培养计划管理系统说明书.pdf --------------------------------------------------------------------------------