├── .gitignore ├── LICENSE ├── README.md ├── __init__.py ├── dist ├── css │ ├── app.2a0c296c.css │ └── chunk-vendors.8f69c8d0.css ├── favicon.ico ├── fonts │ ├── element-icons.535877f5.woff │ └── element-icons.732389de.ttf ├── img │ ├── 44ce51cbfee3ac0249cd771f2ad9a7c2.1237196c.jpg │ ├── ba8bd4e0f53dbde0eedb58c571a98202.47bc6eca.jpg │ ├── kk.f9fde43d.png │ └── mouse.dbd8f926.png ├── index.html ├── js │ ├── app.0a5e3dab.js │ ├── app.0a5e3dab.js.map │ ├── chunk-vendors.3b4c4a20.js │ └── chunk-vendors.3b4c4a20.js.map └── logo.jpg ├── manage.py ├── requirements.txt ├── settings.py ├── test ├── ReadExcel │ ├── main.py │ └── test2.py ├── college.js ├── test.py ├── testUpload.py └── testsql.py ├── testdata ├── 2018-2019学年度第一学期学生综合素质测评分(2017级).xlsx └── 2018-2019学年度第二学期学生综合素质测评分(2017级).xls ├── utils └── api.py └── zhsz_api ├── __init__.py ├── controllers ├── __init__.py ├── auth.py ├── data.py ├── logonav.py └── sql.py ├── extensions.py ├── forms.py └── models.py /.gitignore: -------------------------------------------------------------------------------- 1 | /venv/ 2 | *.pyc 3 | /CreateUser/controllers/__pycache__/auth.cpython-37.pyc 4 | /uploads/__pycache__/up.cpython-37.pyc 5 | /uploads/__pycache__/config.cpython-37.pyc 6 | /CreateUser/__pycache__/__init__.cpython-37.pyc 7 | /CreateUser/__pycache__/extensions.cpython-37.pyc 8 | /CreateUser/__pycache__/forms.cpython-37.pyc 9 | /CreateUser/__pycache__/models.cpython-37.pyc 10 | /CreateUser/controllers/__pycache__/__init__.cpython-37.pyc 11 | /CreateUser/controllers/__pycache__/auth.cpython-37.pyc 12 | /__pycache__/settings.cpython-37.pyc 13 | /migrations 14 | /.idea 15 | /.vscode 16 | /zhsz_api/uploads 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 FormatFa and old_tree and calfhead_admin and zw 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### 学生综合素质可视化分析 后端代码 2 | 3 | 4 | 前端项目地址: 5 | 6 | Gitee: 7 | https://gitee.com/old_tree/zhszweb 8 | 9 | GitHub: 10 | https://github.com/FormatFa/zhszweb 11 | ## 项目配置安装 12 | 13 | ### 前提: 14 | - mysql数据库 15 | - 安装Python3 16 | - 安装pip 17 | - 设置pip源为阿里云的源(推荐) 18 | 修改 ~/.pip/pip.conf(windows下为C:\Users\用户名\pip\pip.ini)文件(没有则新建) 19 | 文件里输入下面的配置 20 | ``` 21 | [global] 22 | 23 | timeout = 6000 24 | 25 | index-url = https://pypi.tuna.tsinghua.edu.cn/simple 26 | 27 | trusted-host = pypi.tuna.tsinghua.edu.cn 28 | ``` 29 | 30 | 31 | 32 | 下面命令在工程根目录执行 33 | 34 | ### 1. 创建虚拟环境 35 | ``` 36 | python3 -m venv venv 37 | ``` 38 | 使用PyCharm 或者 VSCode 等IDE ,就将工程的虚拟环境切换为刚才创建的虚拟环境(在工程根目录下) 39 | 40 | ### 2. pip安装依赖所需依赖 41 | 42 | - 在终端里进入虚拟环境 43 | 44 | ``` 45 | windows 环境 46 | venv\Scripts\activate 47 | Linux 环境 48 | [root@zhsz zhsz_flask]# source venv/bin/activate 49 | ``` 50 | 51 | - 使用pip安装依赖库 52 | ``` 53 | pip install -r requirements.txt 54 | 55 | ``` 56 | 57 | ## 初始化 58 | 59 | ### 1.配置数据库 60 | 修改`settings.py`文件 61 | 设置 MySQL 的 地址 和 用户名密码 62 | 63 | ### 初始化数据库 64 | 65 | 第一次运行执行下面命令创建对应的表 66 | 67 | ``` 68 | python manage.py db init 69 | python manage.py db migrate 70 | python manage.py db upgrade 71 | ``` 72 | 73 | 74 | 75 | ## 启动项目 76 | 77 | 使用命令 78 | `python3 manage.py server` 79 | 80 | 81 | ### 修改维护 82 | 83 | - 生成requirements.txt 84 | 85 | `pip freeze > requirements.txt` 86 | 87 | 88 | ### 开发者 89 | 90 | Gitee 91 | 92 | - [Gitee@old_tree](https://gitee.com/old_tree) 93 | - [Gitee@calfhead_admin](https://gitee.com/calfhead_admin) 94 | - [Gitee@BigdataZW](https://gitee.com/BigdataZW) 95 | - [Gitee@FormatFa](https://gitee.com/FormatFa) 96 | - 97 | GitHub 98 | 99 | - [GitHub@FormatFa](https://github.com/FormatFa) 100 | - [GitHub@CattleHome](https://github.com/CattleHome) 101 | - [GitHub@old_tree](https://github.com/old-tree) 102 | - [GitHub@peterparker-bot](https://github.com/peterparker-bot) -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FormatFa/zhsz_backend/1bcf68fb83f54e8a10874a9e66ef6e04e53685a3/__init__.py -------------------------------------------------------------------------------- /dist/css/app.2a0c296c.css: -------------------------------------------------------------------------------- 1 | .cardtext[data-v-67aedfc7]{color:red;font-size:30px}.chart[data-v-67aedfc7]{width:100%}.el-dropdown-link{cursor:pointer;color:#409eff}.el-icon-arrow-down{font-size:12px}#login{background:url(../img/ba8bd4e0f53dbde0eedb58c571a98202.47bc6eca.jpg);background-size:100% 100%;height:100%;position:fixed;left:0;top:0;width:100%}.el-table .file-no-upload{background:#fdf5e6}.el-table .file-ok{background:#f0f9eb}#bg{background:url(../img/44ce51cbfee3ac0249cd771f2ad9a7c2.1237196c.jpg);background-size:cover;height:100%;position:fixed;left:0;top:0;width:100%}body,html{cursor:url(../img/mouse.dbd8f926.png),auto;cursor:url(../img/kk.f9fde43d.png),pointer} -------------------------------------------------------------------------------- /dist/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FormatFa/zhsz_backend/1bcf68fb83f54e8a10874a9e66ef6e04e53685a3/dist/favicon.ico -------------------------------------------------------------------------------- /dist/fonts/element-icons.535877f5.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FormatFa/zhsz_backend/1bcf68fb83f54e8a10874a9e66ef6e04e53685a3/dist/fonts/element-icons.535877f5.woff -------------------------------------------------------------------------------- /dist/fonts/element-icons.732389de.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FormatFa/zhsz_backend/1bcf68fb83f54e8a10874a9e66ef6e04e53685a3/dist/fonts/element-icons.732389de.ttf -------------------------------------------------------------------------------- /dist/img/44ce51cbfee3ac0249cd771f2ad9a7c2.1237196c.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FormatFa/zhsz_backend/1bcf68fb83f54e8a10874a9e66ef6e04e53685a3/dist/img/44ce51cbfee3ac0249cd771f2ad9a7c2.1237196c.jpg -------------------------------------------------------------------------------- /dist/img/ba8bd4e0f53dbde0eedb58c571a98202.47bc6eca.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FormatFa/zhsz_backend/1bcf68fb83f54e8a10874a9e66ef6e04e53685a3/dist/img/ba8bd4e0f53dbde0eedb58c571a98202.47bc6eca.jpg -------------------------------------------------------------------------------- /dist/img/kk.f9fde43d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FormatFa/zhsz_backend/1bcf68fb83f54e8a10874a9e66ef6e04e53685a3/dist/img/kk.f9fde43d.png -------------------------------------------------------------------------------- /dist/img/mouse.dbd8f926.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FormatFa/zhsz_backend/1bcf68fb83f54e8a10874a9e66ef6e04e53685a3/dist/img/mouse.dbd8f926.png -------------------------------------------------------------------------------- /dist/index.html: -------------------------------------------------------------------------------- 1 | zhszweb
-------------------------------------------------------------------------------- /dist/js/app.0a5e3dab.js: -------------------------------------------------------------------------------- 1 | (function(e){function t(t){for(var s,l,n=t[0],i=t[1],c=t[2],u=0,p=[];u▲第一学期:')+t[s]+'
第二学期:')+a[s]+'
总和:')+(t[s]+a[s])}},title:{text:"".concat(this.stateStore.year," 年度综合素质总分各区间分布")},xAxis:{data:e,name:"分数区间",axisLabel:{interval:0}},yAxis:{name:"个数/人"},legend:{right:0},series:[{stack:"总和",name:"第一学期",type:"bar",data:t},{stack:"总和",name:"第二学期",type:"bar",data:a}]};this.$refs["range"].mergeOptions(s)},set_gpa_score:function(){for(var e=[],t=0;t=0&&l<=15?e.proposal="分数较低需要加强":l>15&&l<=30?e.proposal="分数一般继续努力":l>30&&l<=50&&(e.proposal="分数不错,期待你们班的更好表现")})),this.showLoad(),u.$emit("requestData","班级")},methods:{showLoad:function(){var e=this;Object.keys(this.$refs).forEach((function(t){e.$refs[t].showLoading()}))},hideLoad:function(){var e=this;Object.keys(this.$refs).forEach((function(t){e.$refs[t].hideLoading()}))},intoStudent:function(e,t,a){console.log("进入学生:"+e+" "+t+" "+a),console.log(this.$route),this.$router.push({name:"student",params:{studentid:e.name,classid:this.$route.params["classid"]}})},zhibiaochange:function(e){console.log("改变指标"),console.log(e),this.set_topstudent()},handleChange:function(e){},set_suchindexscore:function(){console.log("显示雷达图,当前学期");for(var e=this.data["suchindexscores"],t=-1,a=0;at&&(t=e[a].value[s]);var o={title:{text:"".concat(this.stateStore.termName()," 各指标雷达图")},tooltip:{},legend:{data:["学院指标平均分","班级指标平均分"],right:0},radar:{name:{textStyle:{color:"#000",backgroundColor:"#999",borderRadius:3,padding:[3,5]}},indicator:[{name:"思想政治",max:t},{name:"身心健康",max:t},{name:"创新创业",max:t},{name:"技术技能",max:t},{name:"志愿服务",max:t},{name:"人文艺术",max:t},{name:"综合素质理论",max:t}]},series:[{name:"学院指标平均分vs班级指标平均分",type:"radar",data:e}]};this.$refs["suchindexscore"].mergeOptions(o)},set_studentnames:function(){var e=this.data["students"]["student"];this.peoples.splice(0,this.peoples.length);for(var t=0;t{b} : {c}%"},toolbox:{feature:{dataView:{readOnly:!1},restore:{},saveAsImage:{}}},legend:{data:e,bottom:0},calculable:!0,series:[{name:"总分区间图",type:"funnel",left:"20%",top:60,bottom:60,width:"80%",min:0,max:50,minSize:"0%",maxSize:"100%",sort:"descending",gap:2,label:{show:!0,position:"inside"},labelLine:{length:10,lineStyle:{width:1,type:"solid"}},itemStyle:{borderColor:"#fff",borderWidth:1},emphasis:{label:{fontSize:20}},data:t}]};console.log(this.$refs["totalscores"]),console.log(a),this.$refs["totalscores"].mergeOptions(a,!1)}},data:function(){return{proposal:[],proposal2:"",stateStore:c.state,nowIndex:"总分Top5",data:$,peoples:["渣渣","渣渣辉"],options:[{value:"思想政治",label:"思想政治Top5"},{value:"身心健康",label:"身心健康Top5"},{value:"创新创业",label:"创新创业Top5"},{value:"技术技能",label:"技术技能Top5"},{value:"志愿服务",label:"志愿服务Top5"},{value:"人文艺术",label:"人文艺术Top5"},{value:"综合素质理论",label:"综合素质理论Top5"},{value:"总分",label:"总分Top5"}],value:"",activeNames:[1]}}},S=k,O=(a("8de1"),Object(x["a"])(S,_,C,!1,null,null,null)),L=O.exports,j=function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("div",[a("el-row",{attrs:{gutter:40}},[a("el-col",{attrs:{span:12}},[a("el-card",{attrs:{"body-style":"padding:34px"}},[a("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[a("span",{staticStyle:{"font-size":"25px"}},[e._v("个人第一学期的基本情况")])]),a("div",{staticStyle:{"font-size":"20px"}},[e._v("第一学期综合素质分:"+e._s(e.data.studentCard1.term1_avlscore))]),a("div",{staticStyle:{"font-size":"20px"}},[e._v("第一学期综合素质全院排名:"+e._s(e.data.studentCard1.term1_yranking))]),a("div",{staticStyle:{"font-size":"20px"}},[e._v("第一学期综合素质全班排名:"+e._s(e.data.studentCard1.term1_cranking))])]),a("el-card",{attrs:{"body-style":"padding:34px"}},[a("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[a("span",{staticStyle:{"font-size":"25px"}},[e._v("个人第二学期的基本情况")])]),a("div",{staticStyle:{"font-size":"20px"}},[e._v("第二学期综合素质分:"+e._s(e.data.studentCard2.term2_avlscore))]),a("div",{staticStyle:{"font-size":"20px"}},[e._v("第二学期综合素质全院排名:"+e._s(e.data.studentCard2.term2_yranking))]),a("div",{staticStyle:{"font-size":"20px"}},[e._v("第二学期综合素质全班排名:"+e._s(e.data.studentCard2.term2_cranking))])])],1),a("el-col",{attrs:{span:12,xs:24}},[a("el-card",[a("v-chart",{ref:"scuhindexscore",staticClass:"chart",attrs:{autoresize:""}})],1)],1)],1),a("el-row",{staticStyle:{"margin-top":"25px"},attrs:{gutter:40}},[a("el-col",{attrs:{span:12,xs:24}},[a("el-card",[a("div",{staticStyle:{"font-size":"20px"}},[e._v("各个指标在全院的排名")]),a("el-table",{attrs:{data:e.CollegeData,fit:"",align:"center"}},[a("el-table-column",{attrs:{prop:"Collegindex",label:"各指标",width:"180"}}),a("el-table-column",{attrs:{prop:"Collegscores",label:"分数",width:"180"}}),a("el-table-column",{attrs:{prop:"Collegranking",label:"排名",width:"180"}})],1)],1)],1),a("el-col",{attrs:{span:12,xs:24}},[a("el-card",[a("div",{staticStyle:{"font-size":"20px"}},[e._v("各个指标在全班的排名")]),a("el-table",{attrs:{data:e.ClassData,fit:"",align:"center"}},[a("el-table-column",{attrs:{prop:"Classindex",label:"各指标",width:"180"}}),a("el-table-column",{attrs:{prop:"Classscores",label:"分数",width:"180"}}),a("el-table-column",{attrs:{prop:"Classranking",label:"排名",width:"180"}})],1)],1)],1)],1),a("el-row",[a("el-col",[a("el-collapse",{on:{change:e.handleChange},model:{value:e.activeNames,callback:function(t){e.activeNames=t},expression:"activeNames"}},[a("el-collapse-item",{attrs:{title:"建议",name:"1"}},[a("div",[e._v(e._s(e.proposal))]),a("div",[e._v(e._s(e.proposal2))])])],1)],1)],1)],1)},D=[],z={studentCard1:{term1_avlscore:34,term1_yranking:299,term1_cranking:12},studentCard2:{term2_avlscore:33,term2_yranking:333,term2_cranking:11},suchindexscores:[{value:[1,3,3,1,2,1,0],name:"学院指标平均分"},{value:[4,3,1,1,2,1,0],name:"班级指标平均分"},{value:[1,4,3,2,1,1,0],name:"学生指标分数"}],data1:{CollegeData:[{Collegindex:"身心健康",Collegscores:60,Collegranking:122},{Collegindex:"思想政治",Collegscores:60,Collegranking:122}]},data2:{ClassData:[{Classindex:"身心健康",Classscores:60,Classranking:122},{Classindex:"思想政治",Classscores:60,Classranking:122}]},scores:{score:40}},T={name:"student",mounted:function(){var e=this;u.$on("studentDataLoad",(function(t){console.log("个人界面请求数据"),console.log(t),e.data=t,e.set_suchindexscore(),e.hideLoad();for(var a=0,s=["思想政治","身心健康","创新创业","技术技能","志愿服务","人文艺术","综合素质理论"],o=0,r=e.data.suchindexscores[2].value,l=0;l<=r.length-2;l+=1)r[l]=0&&a<=15?e.proposal="你的综合素质分较低,有待加强":a>15&&a<=30?e.proposal="你的综合素质分一般,应该适当加强":a>30&&a<=50?e.proposal="你的综合素质分还不错,继续加油":a>50&&a<=100&&(e.proposal="你的综合素质分挺好的")})),this.showLoad(),u.$emit("requestData","个人")},methods:{handleChange:function(e){console.log(e)},showLoad:function(){var e=this;Object.keys(this.$refs).forEach((function(t){e.$refs[t].showLoading()}))},hideLoad:function(){var e=this;Object.keys(this.$refs).forEach((function(t){e.$refs[t].hideLoading()}))},set_suchindexscore:function(){console.log("显示个人当前学期的雷达图");for(var e=this.data["suchindexscores"],t=-1,a=0;at&&(t=e[a].value[s]);var o={title:{text:"".concat(this.stateStore.termName()," 各指标雷达图")},tooltip:{},legend:{data:["学院指标平均分","班级指标平均分","学生指标分数"],right:5},radar:{shape:"circle",axisLine:{},indicator:[{name:"思想政治",max:t,color:"black"},{name:"身心健康",max:t,color:"red"},{name:"创新创业",max:t,color:"orange"},{name:"技术技能",max:t,color:"pink"},{name:"志愿服务",max:t,color:"green"},{name:"人文艺术",max:t,color:"blue"},{name:"综合素质理论",max:t,color:"purple"}]},series:[{name:"学院指标平均分vs班级指标平均分vs学生指标分数",type:"radar",data:e}]};console.log(o),this.$refs["scuhindexscore"].mergeOptions(o)},set_CollegeData:function(){var e=this;this.CollegeData.splice(0,this.CollegeData.length),this.data["data1"]["CollegeData"].forEach((function(t){e.CollegeData.push(t)}))},set_ClassData:function(){var e=this;this.ClassData.splice(0,this.ClassData.length),this.data["data2"]["ClassData"].forEach((function(t){e.ClassData.push(t)}))}},computed:{CollegeData:function(){return this.data.data1.CollegeData},ClassData:function(){return this.data.data2.ClassData}},data:function(){return{proposal:[],proposal2:[],stateStore:c.state,data:z,activeNames:["1"]}}},N=T,E=Object(x["a"])(N,j,D,!1,null,null,null),I=E.exports,Y=function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("div",{attrs:{id:"login"}},[a("el-row",{attrs:{type:"flex",justify:"center"}},[a("el-col",{staticStyle:{"margin-top":"200px"},attrs:{span:5,xs:20}},[a("el-form",{ref:"loginForm",attrs:{model:e.login,rules:e.rules,size:"medium"}},[a("el-form-item",{attrs:{error:e.errors.username,label:"用户名",prop:"username"}},[a("el-input",{model:{value:e.login.username,callback:function(t){e.$set(e.login,"username",t)},expression:"login.username"}})],1),a("el-form-item",{attrs:{error:e.errors.password,label:"密码",prop:"password"}},[a("el-input",{attrs:{"show-password":""},model:{value:e.login.password,callback:function(t){e.$set(e.login,"password",t)},expression:"login.password"}})],1),a("el-form-item",[a("el-button",{attrs:{size:"medium"},on:{click:e.submitLogin}},[e._v("立即登录")])],1),a("a",{attrs:{href:"#"},on:{click:function(t){return e.register()}}},[e._v("没有账号?")])],1)],1)],1)],1)},F=[],q=function(e){return be("/api/auth/login",e)},P=function(e){return be("/api/auth/register",e)},A=function(){return ve("/api/auth/logout")},R=function(e){return be("/api/nav/classes",e)},U=function(){return ve("/api/auth/session")},B=function(e){return be("/api/auth/login/alterPassword",e)},M=a("5c96"),V=a.n(M),G={name:"login",mounted:function(){},beforeRouteUpdate:function(){},created:function(){var e=this;console.log("create...."),u.$on("showLogin",(function(){e.isShow=!0})),console.log("发送隐藏"),u.$emit("hideLogo",!1)},data:function(){return{errors:{username:"",password:""},rules:{username:[{required:!0,message:"请输入用户名",trigger:"blur"}],password:[{required:!0,message:"请输入密码",trigger:"blur"},{min:8,max:16,message:"长度为8到16位",trigger:"blur"}]},isShow:!0,login:{}}},methods:{register:function(){this.$router.replace({name:"register"})},startLogin:function(){var e=this;M["Loading"].service({text:"正在登录....",fullscreen:!0}),q({username:this.login.username,password:this.login.password}).then((function(t){if(M["Loading"].service({fullscreen:!0}).close(),console.log("请求成功"),console.log(t),e.isShow=!1,0==t.code)e.$message({type:"success",message:"登录成功,正在跳转到页面"}),e.$router.push({name:"data"});else{console.log("登录返回非0");var a=t.data;if(console.log(a),void 0!==a.username){var s=a.username.join(",");-1!=s.indexOf("Invalid username")&&(e.errors.username="无效的用户名")}if(void 0!==a.password){var o=a.password.join(",");console.log(o),-1!=o.indexOf("Incorrect password!")&&(e.errors.password="密码错误!")}}})).catch((function(t){M["Loading"].service({fullscreen:!0}).close(),console.log("请求失败"),console.log(t);t.response.data;403==t.response.status?e.$message({type:"error",message:"登录,请检查用户名或密码"}):e.$message({type:"error",message:"登录失败,请检查网络连接"})}))},openLogin:function(){this.isShow=!0},submitLogin:function(){var e=this;console.log("提交登录...."),this.$refs["loginForm"].validate((function(t){t&&e.startLogin()}))}}},W=G,J=(a("d6db"),Object(x["a"])(W,Y,F,!1,null,null,null)),H=J.exports,K=function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("div",[a("el-row",[a("el-col",[a("el-select",{attrs:{placeholder:"打开可视化界面"},on:{change:e.openCollege},model:{value:e.selectCollege,callback:function(t){e.selectCollege=t},expression:"selectCollege"}},e._l(e.storeState.colleges,(function(e){return a("el-option",{key:e,attrs:{label:e,value:e}})})),1),a("el-button",{on:{click:e.truncateFiles}},[e._v("一键清空表")])],1)],1),a("el-row",{attrs:{gutter:40}},[e._e(),a("el-col",{attrs:{span:14,xs:20}},[a("el-card",[a("div",{attrs:{slot:"header"},slot:"header"},[a("span",[e._v("已经上传的数据")]),a("div",{staticStyle:{float:"right"}},[a("div",{staticStyle:{display:"inline","padding-right":"20px"}},[e._v("用户名:"+e._s(e.storeState.login.username))]),a("el-button",{attrs:{type:"success"},on:{click:e.qiandao}},[e._v("每日签到领金币")]),a("el-button",{attrs:{type:"warning"},on:{click:function(t){e.dialogVisible=!0}}},[e._v("修改登录密码")]),a("el-dialog",{attrs:{title:"提示",visible:e.dialogVisible,width:"30%","before-close":e.handleClose},on:{"update:visible":function(t){e.dialogVisible=t}}},[a("el-form",{attrs:{size:"medium"}},[a("el-form-item",{attrs:{label:"原密码",prop:"password1"}},[a("el-input",{attrs:{placeholder:"原密码","show-password":""},model:{value:e.reg.password1,callback:function(t){e.$set(e.reg,"password1",t)},expression:"reg.password1"}})],1),a("el-form-item",{attrs:{label:"新密码",prop:"password2"}},[a("el-input",{attrs:{placeholder:"密码","show-password":""},model:{value:e.reg.password2,callback:function(t){e.$set(e.reg,"password2",t)},expression:"reg.password2"}})],1),a("el-form-item",{attrs:{label:"确认新密码",prop:"password3"}},[a("el-input",{attrs:{placeholder:"密码","show-password":""},model:{value:e.reg.password3,callback:function(t){e.$set(e.reg,"password3",t)},expression:"reg.password3"}})],1)],1),a("span",{staticClass:"dialog-footer",attrs:{slot:"footer"},slot:"footer"},[a("el-button",{on:{click:function(t){e.dialogVisible=!1}}},[e._v("取 消")]),a("el-button",{attrs:{type:"primary"},on:{click:e.changgg}},[e._v("确 定")])],1)],1),a("el-button",{attrs:{type:"danger"},on:{click:e.logout}},[e._v("退出登录")])],1)]),a("span",[e._v("上传新数据")]),a("el-row",[a("el-col",{attrs:{span:4}},[a("el-select",{attrs:{placeholder:"选择学院"},model:{value:e.upload.college,callback:function(t){e.$set(e.upload,"college",t)},expression:"upload.college"}},e._l(e.storeState.colleges,(function(e){return a("el-option",{key:e,attrs:{label:e,value:e}})})),1)],1),a("el-col",{attrs:{span:4}},[a("el-date-picker",{attrs:{type:"year",placeholder:"选择年度"},model:{value:e.upload.year,callback:function(t){e.$set(e.upload,"year",t)},expression:"upload.year"}})],1),a("el-col",{attrs:{span:4}},[a("el-select",{attrs:{type:"year",placeholder:"选择年级"},model:{value:e.upload.grade,callback:function(t){e.$set(e.upload,"grade",t)},expression:"upload.grade"}},e._l(e.uploadYears,(function(e){return a("el-option",{key:e.value,attrs:{label:e.label,value:e.value}})})),1)],1),a("el-col",{attrs:{span:4}},[a("el-select",{model:{value:e.upload.term,callback:function(t){e.$set(e.upload,"term",t)},expression:"upload.term"}},[a("el-option",{attrs:{label:"第一学期",value:"term1"}}),a("el-option",{attrs:{label:"第二学期",value:"term2"}})],1)],1),a("el-col",{attrs:{span:12}},[a("el-upload",{ref:"uploadNew",attrs:{limit:1,multiple:!1,"auto-upload":!1,data:e.uploadData,action:"/api/data/upload","on-success":e.uploadOk,"on-error":e.uploadNotOk,"on-change":e.uploadChange}},[a("el-button",{attrs:{slot:"trigger"},slot:"trigger"},[e._v("选择对应的Excel文件")]),a("el-button",{on:{click:e.submitUploadNew}},[e._v("上传数据")])],1)],1)],1),a("el-table",{attrs:{data:e.uploaded,"row-class-name":e.fileStateClassName}},[a("el-table-column",{attrs:{label:"学院",prop:"college"}}),a("el-table-column",{attrs:{label:"年度",prop:"year"}}),a("el-table-column",{attrs:{formatter:e.formatGrade,label:"年级",prop:"grade"}}),a("el-table-column",{attrs:{formatter:e.formatTerm,label:"学期",prop:"term"}}),a("el-table-column",{attrs:{formatter:e.formatState,label:"状态",prop:"state"}}),a("el-table-column",{attrs:{label:"操作"},scopedSlots:e._u([{key:"default",fn:function(t){return[a("el-button",{on:{click:function(a){return e.deleteFile(t.row)}}},[e._v("删除数据")]),1==t.row.state?a("el-button",{on:{click:function(a){return e.parseFile(t.row)}}},[e._v("解析数据")]):e._e()]}}])})],1)],1)],1)],1)],1)},Q=[],X=function(e){return be("/api/data/handle",e,{timeout:5e4})},Z=function(e){return be("/api/data/delete",e)},ee=function(e){return be("/api/data/truncate")},te=function(e){return be("/api/data/uploaded")};function ae(e,t){e.splice(0,e.length);for(var a=0;ae-3;a-=1)t.push({label:a+"级",value:a+""});return t}},methods:{openCollege:function(e){console.log("打开学院:",e),this.$router.push({name:"college",params:{collegeid:e}})},qiandao:function(){this.$message({message:"签到成功,金币+10",type:"warning"})},changgg:function(){var e=this;this.reg.password2==this.reg.password3?(this.dialogVisible=!1,console.log("调用监听修改密码"),B({username:this.storeState.login.username,old_password:this.reg.password1,password:this.reg.password2,password2:this.reg.password3}).then((function(t){console.log("请求成功.."),console.log(t),0==t.code?(e.$message({showClose:!0,message:"密码修改成功,跳转到登录界面",type:"success"}),e.$router.push({name:"login"})):e.$message({showClose:!0,message:"密码失败:"+t.msg,type:"error"})})).catch((function(e){console.log("请求失败.")}))):this.$message({showClose:!0,message:"密码不一致",type:"error"})},handleClose:function(e){this.$confirm("确认关闭?").then((function(t){e()})).catch((function(e){}))},logout:function(){var e=this;A().then((function(t){0==t.code?(e.$message({message:"登出成功!"}),e.$router.push({name:"login"})):se(e,t.msg)})).catch((function(e){}))},submitUploadNew:function(){console.log("上传数据..."),""!=this.upload.year?(this.uploadData["year"]=this.upload.year.getFullYear(),this.uploadData["grade"]=this.upload.grade,this.uploadData["term"]=this.upload.term,this.uploadData["college"]=this.upload.college,this.$refs.uploadNew.submit()):this.$message("年度没有选择!!")},requestUpload:function(){var e=this;te().then((function(t){console.log("获取已上传的数据:"),console.log(t),0==t.code?ae(e.uploaded,t.data):e.$alert(t.data,"失败",{confirmButtonText:"确定"})})).catch((function(e){console.log("获取已上传的数据失败")}))},formatGrade:function(e,t,a,s){return a?4==a.length?a.substring(2,4)+"级":a:"null"},formatTerm:function(e,t,a,s){return"term1"==a?"第一学期":"term2"==a?"第二学期":a},formatState:function(e,t,a,s){return 0==a?"未上传":1==a?"未解析":2==a?"解析完成":void 0},truncateFiles:function(){var e=this;ee().then((function(t){console.log("清空表成功.."),e.switchYear(e.year.getFullYear())})).catch((function(e){console.log("清空表失败..")}))},deleteFile:function(e){var t=this,a={year:e.year,grade:e.grade,term:e.term,college:e.college};M["Loading"].service({text:"删除数据文件和数据库里的记录....",fullscreen:!0}),Z(a).then((function(e){M["Loading"].service({fullscreen:!0}).close(),console.log("ffff"),console.log(e),0==e.code?(t.$message({type:"success",message:"清空数据成功:"+e.msg}),t.switchYear(t.year.getFullYear())):t.$alert(e.msg,"删除数据失败",{confirmButtonText:"确定"})})).catch((function(e){M["Loading"].service({fullscreen:!0}).close(),console.log(e),t.$alert(e.data,"服务器响应失败,清空数据失败",{confirmButtonText:"确定"})}))},parseFile:function(e){var t=this;console.log("解析数据:"),console.log(e),M["Loading"].service({text:"解析数据到数据库中....",fullscreen:!0});var a={year:e.year,grade:e.grade,term:e.term,college:e.college};X(a).then((function(e){M["Loading"].service({fullscreen:!0}).close(),console.log(e),0!=e.code?t.$alert(e.msg,"服务器响应上传失败",{confirmButtonText:"确定"}):t.$message({type:"success",message:"解析成功"}),t.switchYear(t.year.getFullYear())})).catch((function(e){t.$alert("捕捉到异常:"+e,"解析错误",{confirmButtonText:"确定"}),M["Loading"].service({fullscreen:!0}).close()}))},uploadOk:function(e,t,a){0!=e.code?this.$alert(e.msg,"服务器响应上传失败",{confirmButtonText:"确定"}):this.$message({type:"success",message:"上传成功"}),this.switchYear(this.year.getFullYear()),this.$refs.uploadNew.clearFiles()},uploadNotOk:function(e,t,a){console.log("上传文件不成功..."),console.log(e),this.$alert(e,"上传失败",{confirmButtonText:"确定"}),this.$refs.uploadNew.clearFiles()},uploadChange:function(e,t){if(console.log("文件状态改变:"),console.log(e),console.log(t),1==t.length){var a=t[0].name;console.log("添加文件名:"+a);var s=/(\d+)级/g,o=/第(.)学期/g,r=/(\d{4})-\d{4}/g,l=s.exec(a),n=o.exec(a),i=r.exec(a);console.log("尝试在文件名里查找参数:"+l),console.log(n),console.log(i),2==l.length&&2==n.length&&2==i.length?(n=n[1],"一"==n?n="term1":"二"==n&&(n="term2"),l=l[1],i=i[1],this.$message({type:"success",message:"文件名里获取年度等数据成功,年度:".concat(i," 年级:").concat(l," 学期:").concat(n)}),this.upload.grade=l,this.upload.term=n,this.upload.year=new Date(i,1,1)):this.$message({type:"error",message:"文件名里获取年度等数据失败,请手动选择"})}},getUploadPostData:function(e){return{year:e.year,grade:e.grade,term:e.term}},fileStateClassName:function(e,t){return 0==e.row.state?"file-no-upload":1==e.row.state?"file-ok":void 0},changeYear:function(e){this.switchYear(e.getFullYear())},switchYear:function(e){this.requestUpload(),console.log("选择年份:"+e)},submitUpload:function(){this.$refs.upload.submit()}}},re=oe,le=(a("af04"),Object(x["a"])(re,K,Q,!1,null,null,null)),ne=le.exports,ie=function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("div",{attrs:{id:"bg"}},[a("el-row",{staticStyle:{"margin-right":"100px","margin-top":"110px"},attrs:{type:"flex",justify:"center"}},[a("el-col",{attrs:{span:5,xs:20}},[a("div",{staticStyle:{"font-size":"44px","margin-bottom":"20px"}},[e._v("欢迎注册")]),a("div",{staticStyle:{"font-size":"28px","margin-bottom":"64px"}},[e._v("\n 每一天,乐在沟通\n "),a("div",{staticStyle:{color:"#359eff",float:"right"}})]),a("el-form",{attrs:{size:"medium"}},[a("el-form-item",{attrs:{error:e.errors.username,label:"用户名",prop:"username"}},[a("el-input",{attrs:{placeholder:"用户名"},model:{value:e.reg.username,callback:function(t){e.$set(e.reg,"username",t)},expression:"reg.username"}})],1),a("el-form-item",{attrs:{error:e.errors.password,label:"密码",prop:"password"}},[a("el-input",{attrs:{placeholder:"密码","show-password":""},model:{value:e.reg.password,callback:function(t){e.$set(e.reg,"password",t)},expression:"reg.password"}})],1),a("el-form-item",{attrs:{error:e.errors.password2,label:"确认密码",prop:"password2"}},[a("el-input",{attrs:{placeholder:"密码","show-password":""},model:{value:e.reg.password2,callback:function(t){e.$set(e.reg,"password2",t)},expression:"reg.password2"}})],1),a("el-form-item",[a("el-button",{attrs:{type:"primary",size:"medium"},on:{click:function(t){return e.submit()}}},[e._v("立即注册")])],1),a("el-form-item",[a("el-tooltip",{attrs:{placement:"top"}},[a("div",{attrs:{slot:"content"},slot:"content"},[e._v("相关哈哈哈哈哈")]),a("div",[a("el-checkbox",{on:{change:e.agree},model:{value:e.isAgree,callback:function(t){e.isAgree=t},expression:"isAgree"}},[e._v("我已阅读并同意相关服务条款和隐私政策")]),a("img",{attrs:{onclick:"",src:"/favicon.ico"}})],1)])],1)],1)],1)],1)],1)},ce=[],de=(a("3c43"),{name:"bg",created:function(){u.$emit("hideLogo",!1)},methods:{agree:function(){},submit:function(){var e=this;this.isAgree?this.reg.password==this.reg.password2?(M["Loading"].service({text:"正在注册....",fullscreen:!0}),P({username:this.reg.username,password:this.reg.password}).then((function(t){if(M["Loading"].service({fullscreen:!0}).close(),console.log("注册结果:"),console.log(t),0==t.code)e.$message({showClose:!0,message:"注册成功,正在跳转到登录界面...",type:"success"}),e.$router.replace({name:"login"});else{var a=t.data;if(void 0!==a.username){var s=a.username.join(",");-1!=s.indexOf("already exists!")&&(e.errors.username="用户名已存在")}if(void 0!==a.password){var o=a.password.join(",");"Field must be between 8 and 16 characters long."==o&&(e.errors.password="密码必须在8到16各长度之间")}}})).catch((function(t){M["Loading"].service({fullscreen:!0}).close(),console.log(t),console.log("注册失败:"),e.$message({type:"error",message:"注册失败"})}))):this.errors.password2="两次密码不一样":this.$message({message:"请勾选同意相关协议",type:"warning"})}},data:function(){return{isAgree:!1,errors:{username:"",password:"",password2:""},reg:{username:"",password:"",password2:""}}}}),ue=de,pe=(a("2cfd"),Object(x["a"])(ue,ie,ce,!1,null,null,null)),ge=pe.exports;s["default"].use(m["a"]);var me=[{path:"/zhzs/:collegeid",component:w,name:"college"},{path:"/zhzs/:collegeid/:classid/:studentid",component:I,name:"student"},{path:"/zhzs/:collegeid/:classid",component:L,name:"class"},{path:"/login",component:H,name:"login"},{path:"/",component:ne,name:"data"},{path:"/data",component:ne,name:"data"},{path:"/register",component:ge,name:"register"}],he=new m["a"]({routes:me}),fe=he;function ve(e,t){return new Promise((function(a,s){g.a.get(e,{params:t}).then((function(e){a(e.data)})).catch((function(e){s(e)}))}))}function be(e,t,a){return new Promise((function(s,o){g.a.post(e,t,a).then((function(e){s(e.data)})).catch((function(e){o(e)}))}))}g.a.defaults.withCredentials=!0,g.a.defaults.timeout=3e3,g.a.defaults.headers.post["Content-Type"]="Content-Type:application/json;charset=UTF-8",g.a.interceptors.response.use((function(e){return console.log("请求拦截:成功"),200===e.status?Promise.resolve(e):Promise.reject(e)}),(function(e){if(console.log("拦截失败"),void 0===e["response"])return Promise.reject(e.message);switch(console.log(e.response),e.response.status){case 401:Object(M["Message"])({type:"error",message:"没登录,重定向到登录界面"}),console.log("-------------重定向................"),fe.replace({name:"login"});break;case 403:break}return Promise.reject(e)}));var xe={name:"app-logo",mounted:function(){var e=this;u.$on("hideLogo",(function(t){console.log("接受是否loggo:"+t),e.showSelect=t})),u.$on("requestData",(function(t){console.log("来自:".concat(t,"的请求重新加载数据事件")),e.requestNav()}))},created:function(){var e=this;console.log("创建logo组件......."),this.$router.afterEach((function(e,t){console.log("全局after each")})),this.$router.beforeEach((function(t,a,s){console.log("Logo.vue beforeEach....."+e.$router.currentRoute.name),s()}))},computed:{collegename:function(){return console.log("获取学院名字..."),console.log(this.$route.params),-1!=Object.keys(this.$route.params).indexOf("collegeid")?this.$route.params["collegeid"]:""}},beforeRouteEnter:function(e,t,a){console.log("beforeRouteEnter...."),console.log(e)},methods:{requestNav:function(){var e=this;this.loading=!0,R({college:this.collegename}).then((function(t){e.loading=!1,console.log("请求logo导航数据成功!!"),console.log(t),ae(e.classes,t.data.classes),ae(e.years,t.data.years),console.log("组件的班级..."),console.log(e.classes),e.year=e.years[0],e.selectYear()})).catch((function(t){e.loading=!1,e.showFailDialog("加载年度和班级列表数据失败!!",e.requestNav),e.selectYear()}))},home:function(){this.$router.push({name:"data"})},intoClass:function(e,t){console.log("进入班级:"+e);var a=e.join("");this.$route.params["classid"]=a,this.$router.push({name:"class",params:{classid:a}})},selectYear:function(){if(this.showSelect=!0,console.log("当前路由:"),console.log(this.$router.currentRoute),console.log("选择的year:"+this.year+" term:"+this.term),c.setYear(this.year),c.setTerm(this.term),this.loading=!0,"college"==this.$router.currentRoute.name)this.requestCollege();else if("class"==this.$router.currentRoute.name){var e=this.$router.currentRoute.params["classid"];this.requestClass(e)}else"student"==this.$router.currentRoute.name?this.requestStudent(this.$router.currentRoute.params["studentid"],this.$router.currentRoute.params["classid"]):this.loading=!1},showFailDialog:function(e,t){this.$confirm(e,"加载数据失败",{confirmButtonText:"重试",cancelButtonText:"显示测试数据",callback:function(e){console.log("开始重试..."),console.log(e),"confirm"==e&&void 0!=t&&t()}})},requestCollege:function(){var e=this;be("/api/collage",{college:this.collegename,year:c.state.year,term:c.state.term}).then((function(t){console.log("请求学院数据成功:.."),console.log(t),e.loading=!1,Object.assign(d,t),u.$emit("collegeDataLoad",d)})).catch((function(t){console.warn("请求学院界面数据失败,发送测试数据...>>>"),e.showFailDialog("获取学院数据失败:\n"+t,e.selectYear),e.loading=!1,u.$emit("collegeDataLoad",d)}))},requestClass:function(e){var t=this;console.log("-------------------请求班级数据------------------"),be("/api/banji",{college:this.collegename,classid:e,year:c.state.year,term:c.state.term}).then((function(e){console.log("请求班级数据:.."),console.log(e),t.loading=!1,Object.assign($,e),u.$emit("classDataLoad",$)})).catch((function(e){console.log("请求数据失败>>>"),console.log(e),t.loading=!1,u.$emit("classDataLoad",$),t.showFailDialog("获取班级数据失败:\n"+e,t.selectYear)}))},requestStudent:function(e,t){var a=this;console.log("请求学生数据...."),console.log(this.$route.params),be("/api/geren",{college:this.collegename,stu_id:e,year:c.state.year,term:c.state.term,classid:t}).then((function(e){console.log("请求个人的数据:.."),console.log(e),console.log(Object(i["a"])(e)),a.loading=!1,Object.assign(z,e),u.$emit("studentDataLoad",z)})).catch((function(e){a.$alert(e,"服务器响应失败",{confirmButtonText:"确定"}),console.log("请求数据失败>>>----------"),console.log(e),a.showFailDialog("获取学生数据失败:\n"+e,a.selectYear),a.loading=!1,u.$emit("studentDataLoad",z)}))}},data:function(){return{showSelect:!1,loading:!1,year:c.state.year,term:c.state.term,classes:[{label:"17",value:"17",children:[{label:"大数据",value:"bigdata"},{label:"云计算",value:"clound"}]},{label:"18",value:"18",children:[{label:"大数据",value:"bigdata"},{label:"云计算",value:"clound"}]}],years:[],terms:[{value:"term1",label:"第一学期"},{value:"term2",label:"第二学期"},{value:"year",label:"年度"}]}}},ye=xe,we=Object(x["a"])(ye,l,n,!1,null,"18e1e646",null),_e=we.exports,Ce={name:"app",data:function(){return{}},components:{Logo:_e},methods:{}},$e=Ce,ke=(a("034f"),Object(x["a"])($e,o,r,!1,null,null,null)),Se=ke.exports,Oe=(a("0fae"),a("9ca8")),Le=(a("94b1"),a("c037"),a("ef97"),a("8deb"),a("a4b1"),a("15af"),a("d28f"),a("007d"),a("627c"),a("f219"),a("98c9"));s["default"].use(Le["a"]),s["default"].component("v-chart",Oe["a"]),s["default"].config.productionTip=!1,s["default"].use(V.a),new s["default"]({render:function(e){return e(Se)},router:fe}).$mount("#app")},"64a9":function(e,t,a){},"8de1":function(e,t,a){"use strict";var s=a("934c"),o=a.n(s);o.a},"934c":function(e,t,a){},9605:function(e,t,a){},a9e7:function(e,t,a){},af04:function(e,t,a){"use strict";var s=a("9605"),o=a.n(s);o.a},c512:function(e,t,a){},d6db:function(e,t,a){"use strict";var s=a("a9e7"),o=a.n(s);o.a},e07e:function(e,t,a){},f631:function(e,t,a){"use strict";var s=a("c512"),o=a.n(s);o.a}}); 2 | //# sourceMappingURL=app.0a5e3dab.js.map -------------------------------------------------------------------------------- /dist/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FormatFa/zhsz_backend/1bcf68fb83f54e8a10874a9e66ef6e04e53685a3/dist/logo.jpg -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from zhsz_api import create_app 4 | from flask_script import Manager,Server 5 | from flask_migrate import MigrateCommand,Migrate 6 | from zhsz_api.models import db,User 7 | app=create_app() 8 | 9 | migrate=Migrate(app,db) 10 | 11 | manager=Manager(app=app) 12 | manager.add_command("server",Server()) 13 | manager.add_command("db",MigrateCommand) 14 | 15 | #自定义命令, 修改用户密码 16 | @manager.option('-u','--user',dest='user') 17 | @manager.option('-p','--password',dest='password') 18 | def passwd(user,password): 19 | from zhsz_api.controllers.auth import alterPassword 20 | print(user,password) 21 | result = alterPassword(user,password,checkOld=False) 22 | print("修改密码结果:",result) 23 | 24 | @manager.shell 25 | def make_shell_context(): 26 | return dict(app=app,db=db,User=User) 27 | 28 | 29 | if __name__ == '__main__': 30 | manager.run() 31 | # vs code 调试时使用 32 | # app.run(host='0.0.0.0') 33 | 34 | 35 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | alembic==1.3.1 2 | astroid==2.3.3 3 | bcrypt==3.1.7 4 | cffi==1.13.2 5 | Click==7.0 6 | colorama==0.4.1 7 | cryptography==2.8 8 | defusedxml==0.6.0 9 | Flask==1.1.1 10 | Flask-Bcrypt==0.7.1 11 | Flask-Cors==3.0.8 12 | Flask-Login==0.4.1 13 | Flask-Migrate==2.5.2 14 | Flask-OpenID==1.2.5 15 | Flask-Script==2.0.6 16 | Flask-SQLAlchemy==2.4.1 17 | Flask-WTF==0.14.2 18 | isort==4.3.21 19 | itsdangerous==1.1.0 20 | Jinja2==2.10.3 21 | lazy-object-proxy==1.4.3 22 | Mako==1.1.0 23 | MarkupSafe==1.1.1 24 | mccabe==0.6.1 25 | numpy==1.17.4 26 | pandas==0.25.3 27 | pycparser==2.19 28 | pylint==2.4.4 29 | PyMySQL==0.9.3 30 | python-dateutil==2.8.1 31 | python-editor==1.0.4 32 | python3-openid==3.1.0 33 | pytz==2019.3 34 | six==1.13.0 35 | SQLAlchemy==1.3.11 36 | typed-ast==1.4.0 37 | Werkzeug==0.16.0 38 | wrapt==1.11.2 39 | WTForms==2.2.1 40 | xlrd==1.2.0 41 | -------------------------------------------------------------------------------- /settings.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | import pymysql 4 | from sqlalchemy import create_engine 5 | 6 | here = os.path.dirname(__file__) 7 | class Config(object): 8 | SECRET_KEY = '\x83u\x1ah\xd1\xa2\xb2\xac\xbf\xa5A\xba\x83[C."\xdc\xd9\xe0\xe5N\xaf\x80' 9 | 10 | RECAPTCHA_PUBLIC_KEY='ADASDGSDVGFS56465FSD1F2SDF452' 11 | 12 | PECAPTCHA_PRIVATE_KEY='ADASDGSDVGFS87487-8615546221' 13 | 14 | DEBUG = True 15 | 16 | database="mysql" 17 | 18 | #数据库是mysql时的配置 19 | 20 | 21 | DATABASE = 'GK_ZH' 22 | DIALECT = 'mysql' 23 | DRIVER = 'pymysql' 24 | USERNAME = 'root' 25 | PASSWORD = 'root' 26 | HOST = 'localhost' 27 | PORT = 3306 28 | 29 | 30 | conn = pymysql.connect( 31 | host=HOST, # 你的主机IP 32 | port=PORT, # 主机端口,不能加双引号 33 | user=USERNAME, # MySQL用户 34 | password=PASSWORD, # MySQL密码 35 | charset='utf8' # 使用的编码格式,不能使用 utf-8 ,不能加多一个横杠 36 | ) 37 | db = conn.cursor() # 创建光标 38 | 39 | db.execute("create database if not exists GK_ZH character set utf8;") # 创建数据库 40 | db.execute("use GK_ZH;") 41 | conn.commit() # 一定要进行事务更新 42 | SQLALCHEMY_DATABASE_URI = '{}+{}://{}:{}@{}:{}/{}?charset=utf8'.format(DIALECT, DRIVER,USERNAME,PASSWORD, HOST, PORT, DATABASE) 43 | #sqlite 时有问题 44 | # #数据库为sqlite 时的 配置 45 | # elif database=="sqlite": 46 | # SQLALCHEMY_DATABASE_URI = 'sqlite:///C:/Users/bigdata/Documents/zhsz/zhsz_flask/zhsz.db' 47 | # conn = sqlite3.connect("C:/Users/bigdata/Documents/zhsz/zhsz_flask/zhsz.db") 48 | # db = conn.cursor() 49 | 50 | engine = create_engine(SQLALCHEMY_DATABASE_URI, echo=True) 51 | 52 | 53 | 54 | # 生产环境 55 | class ProConfig(Config): 56 | pass 57 | 58 | ## 开发环境 59 | class DevConfig(Config): 60 | 61 | pass 62 | #DB_CONNECT_STRING = 'mysql+pymysql://root:root@localhost:3306/test2?charset=utf8' 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | class FileConfig(): 71 | need_word={ 72 | '学号':'style_id', 73 | '姓名':'stu_name', 74 | '思想政治':'political_edu', 75 | '身心健康':'physical_heal', 76 | '创新创业':'innovation_entrep', 77 | '技术技能':'technical_skills', 78 | '志愿服务':'volunte', 79 | '人文艺术':'human_art', 80 | '综合素质理论':'zh_theory', 81 | '总分':'score', 82 | 'GPA(教务处提供)':'GPA', 83 | '综合成绩':'zh_score', 84 | '班级':'gk_class', 85 | '年级':'grade', 86 | '学期': 'semester', 87 | '年度':'year', 88 | '学院':'college' 89 | } 90 | 91 | key=list(need_word.keys()) 92 | 93 | need_columns = [ 94 | ['学号', '姓名', '思想政治', '身心健康', '创新创业', '技术技能', '志愿服务', '人文艺术', '综合素质理论', '总分', 'GPA(教务处提供)', '综合素质测评分(P2)', '排名','班级'], 95 | ['学号', '姓名', '思想政治', '身心健康', '创新创业', '技术技能', '志愿服务', '人文艺术', '综合素质理论', '总分', 'GPA(教务处提供)', '综合成绩', '排名', '班级'], 96 | ['学号', '姓名', '思想政治', '身心健康', '创新创业', '技术技能', '志愿服务', '人文艺术', '综合素质理论', '总分', 'GPA(教务处导出)', '综合素质测评分', '排名','班级'], 97 | ] 98 | 99 | 100 | 101 | config = DevConfig() 102 | 103 | 104 | -------------------------------------------------------------------------------- /test/ReadExcel/main.py: -------------------------------------------------------------------------------- 1 | import os 2 | import re 3 | 4 | import pandas as pd 5 | import pymysql 6 | from sqlalchemy import create_engine 7 | import xlrd 8 | 9 | # connent=create_engine('mysql+pymysql://root:root@localhost:3306/reads_table?charset=utf8') 10 | ''' 11 | 测试智能读取数据,不管里面有多少个sheet 12 | ''' 13 | 14 | need_columns = [ 15 | ['学号', '姓名', '思想政治', '身心健康', '创新创业', '技术技能', '志愿服务', '人文艺术', '综合素质理论', '总分', 'GPA(教务处提供)', '综合素质测评分(P2)', '排名','班级'], 16 | ['学号', '姓名', '思想政治', '身心健康', '创新创业', '技术技能', '志愿服务', '人文艺术', '综合素质理论', '总分', 'GPA(教务处提供)', '综合成绩', '排名', '班级'], 17 | ['学号', '姓名', '思想政治', '身心健康', '创新创业', '技术技能', '志愿服务', '人文艺术', '综合素质理论', '总分', 'GPA(教务处导出)', '综合素质测评分', '排名', '班级'], 18 | ] 19 | need_word={ 20 | '学号':'style_id', 21 | '姓名':'stu_name', 22 | '思想政治':'political_edu', 23 | '身心健康':'physical_heal', 24 | '创新创业':'innovation_entrep', 25 | '技术技能':'technical_skills', 26 | '志愿服务':'volunte', 27 | '人文艺术':'human_art', 28 | '综合素质理论':'zh_theory', 29 | '总分':'score', 30 | 'GPA(教务处提供)':'GPA', 31 | '综合成绩':'zh_score', 32 | '班级':'class', 33 | '年级':'year', 34 | '学期':'semester', 35 | } 36 | 37 | key=list(need_word.keys()) 38 | 39 | CURRENT = os.path.dirname(os.path.dirname(__file__)) 40 | UPLOAD_PATH = CURRENT + '/uploads/static/' 41 | UPDATA_PATH = CURRENT + '/uploads/updata' 42 | 43 | 44 | filess = ['2018-2019学年度第二学期学生综合素质测评分(2017级).xls', '2018-2019学年度第一学期学生综合素质测评分(2017级).xls', 45 | '2018-2019学年度第二学期学生综合素质测评分(2018级).xls', '2018-2019学年度第一学期学生综合素质测评分(2018级).xls'] 46 | 47 | # 循环数据文件 48 | filename='2018-2019学年度第二学期学生综合素质测评分(2018级).xls' 49 | files=UPLOAD_PATH+filename 50 | 51 | save_csv=UPDATA_PATH+filename.split('.')[0]+'.csv' 52 | 53 | excel = pd.ExcelFile(files) 54 | big_data_name = excel.sheet_names # 拿到所有的sheetname 55 | 56 | for needs in need_columns: # 循环所有可能出现的表头 57 | #增加多两列数据 58 | for i in big_data_name: # 循环所有的sheetname 59 | data = pd.read_excel(files, sheet_name=i, header=2) 60 | headers = data.columns.values.tolist() # 将表头转换成列表的形式 61 | if headers == needs: # 将可能出现的表头与excel里面的header对应 62 | # sheet_name = '大数据' # 成功就将其表头转换成大数据 63 | data = data.drop(columns=['排名']) # 删除排名 64 | #print(data.head(2)) 65 | data['年级'] = re.findall('\w+级', filename)[0] # 参数expand=True在一组返回值的情况下,返回数据框 66 | data['学期'] = re.findall('.*?(第.*?期).*?', filename)[0] 67 | # #data.to_excel(file_path, header=2, index=False) 68 | head = data.columns.tolist() 69 | app = [] 70 | for i in range(0, len(key)): 71 | if head[i] == key[i]: 72 | pass 73 | else: 74 | head[i] = key[i] 75 | 76 | for i in head: 77 | app.append(need_word[i]) 78 | data.columns = app 79 | data.to_csv(save_csv, encoding='utf-8', index=False) 80 | print(data.head(2)) 81 | 82 | 83 | 84 | # excels=pd.read_excel(files,header=2) 85 | # print(excels.shape) 86 | # print(excels.columns) 87 | -------------------------------------------------------------------------------- /test/ReadExcel/test2.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | import pandas as pd 4 | import re 5 | import xlwt 6 | import xlrd 7 | import pymysql 8 | from sqlalchemy import create_engine 9 | #智能导入系统 10 | 11 | need_word={ 12 | '学号':'style_id', 13 | '姓名':'stu_name', 14 | '思想政治':'political_edu', 15 | '身心健康':'physical_heal', 16 | '创新创业':'innovation_entrep', 17 | '技术技能':'technical_skills', 18 | '志愿服务':'volunte', 19 | '人文艺术':'human_art', 20 | '综合素质理论':'zh_theory', 21 | '总分':'score', 22 | 'GPA(教务处提供)':'GPA', 23 | '综合成绩':'zh_score', 24 | '班级':'gk_class', 25 | '年级':'year', 26 | '学期':'semester', 27 | } 28 | key=list(need_word.keys()) 29 | 30 | DB_CONNECT_STRING = 'mysql+pymysql://root:root@localhost:3306/gk_zh?charset=utf8' 31 | engine = create_engine(DB_CONNECT_STRING,echo=True) 32 | 33 | 34 | files = '2018-2019学年度第二学期学生综合素质测评分(2017级).xls' 35 | CURRENT = os.path.dirname(os.path.dirname(__file__)) 36 | 37 | UPDATA_PATH = CURRENT + '/uploads/updata/' 38 | file_path=UPDATA_PATH+files 39 | 40 | 41 | save_csv=UPDATA_PATH+files.split('.')[0]+'.csv' 42 | data=pd.read_excel(files,header=2,sheet_name='Sheet2',converters={u'学号':str}) 43 | 44 | print(data['学号']) 45 | 46 | data=data.drop(columns=['排名']) 47 | data['年级'] = re.findall('\w+级',files)[0] # 参数expand=True在一组返回值的情况下,返回数据框 48 | data['学期'] = re.findall('.*?(第.*?期).*?', files)[0] 49 | 50 | # data.to_excel(file_path,sheet_name="大数据",encoding='utf-8',header=2) 51 | # print(data.head(2)) 52 | head=data.columns.tolist() 53 | app=[] 54 | for i in range(0, len(key)): 55 | if head[i] == key[i]: 56 | pass 57 | else: 58 | head[i] = key[i] 59 | 60 | for i in head: 61 | app.append(need_word[i]) 62 | data.columns=app 63 | #data.to_csv(save_csv,encoding='utf-8',index=False) 64 | print(data.head(2)) 65 | #data.to_sql('bigdata', con=engine,if_exists='append',index=False) 66 | 67 | 68 | 69 | # CURRENT=os.path.dirname(os.path.dirname(__file__)) 70 | # UPLOAD_PATH=CURRENT+'/uploads/static' 71 | # files=os.path.join(UPLOAD_PATH, 'aa.xls') 72 | # excel = pd.read_excel(files, header=2) 73 | # 74 | # print(excel.head(3)) 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | #智能建议系统 83 | -------------------------------------------------------------------------------- /test/college.js: -------------------------------------------------------------------------------- 1 | export const college={ 2 | //基本信息,通过查询某一年获取 3 | basicCard:{ 4 | "year_score":123, 5 | "term1_score":90, 6 | "term2_score":120 7 | }, 8 | //某年度,某学期,所有 指标和对应的平均分 xx年y学期 9 | indexes:{ 10 | //所有的指标 11 | indexes:["身心健康","思想政治","创新创业"], 12 | //上面指标对应的分数(平均分) 13 | scores:[100,200] 14 | }, 15 | // top 总分学生和班级 16 | top:{ 17 | //按各个指标或者平均分的排名 18 | "平均分":{ 19 | //按平均分的top 20 | classes:[{ 21 | name:"17大数据1班", 22 | id:"17bigdata1", 23 | score:129 24 | },{ 25 | name:"17大数据2班", 26 | id:"17bigdata2", 27 | score:80 28 | }], 29 | students:[ 30 | { 31 | name:"小李", 32 | score:420 33 | }, 34 | { 35 | name:"小菜", 36 | score:350 37 | }, 38 | { 39 | name:"小大", 40 | score:200 41 | } 42 | 43 | ] 44 | }, 45 | //按某个指标的top 46 | "身心健康":{ 47 | classes:[{ 48 | name:"class1", 49 | score:12 50 | },{ 51 | name:"class2", 52 | score:8 53 | }], 54 | students:[ 55 | { 56 | name:"小明", 57 | score:300 58 | }, 59 | { 60 | name:"小绿", 61 | score:250 62 | }, 63 | { 64 | name:"小红", 65 | score:200 66 | } 67 | 68 | ] 69 | }, 70 | "思想政治":{ 71 | classes:[{ 72 | name:"class1", 73 | score:15 74 | },{ 75 | name:"class2", 76 | score:12 77 | }], 78 | students:[ 79 | { 80 | name:"小李", 81 | score:300 82 | }, 83 | { 84 | name:"小绿", 85 | score:50 86 | }, 87 | { 88 | name:"小孙", 89 | score:20 90 | } 91 | 92 | ] 93 | }, 94 | "创新创业":{ 95 | classes:[{ 96 | name:"class1", 97 | score:19 98 | },{ 99 | name:"class2", 100 | score:13 101 | }], 102 | students:[ 103 | { 104 | name:"小蓝", 105 | score:30 106 | }, 107 | { 108 | name:"小紫", 109 | score:20 110 | }, 111 | { 112 | name:"小红", 113 | score:10 114 | } 115 | 116 | ] 117 | } 118 | 119 | }, 120 | 121 | //分数区间数据,某个年度两个学期的数据 122 | "range":{ 123 | "ranges":["(0-10]","(10-20]","(20-30]"], 124 | //分数出现的范围的字符串 125 | "term1_scores":[10,30,25], 126 | "term2_scores":[20,40,55] 127 | }, 128 | // 根据年度字段 两个学期的 gpa 和成绩数据 129 | "gpa_score":{ 130 | gpas:[4.1,4,2,4,3], 131 | scores:[20,30,40] 132 | }, 133 | //学院 每年的总平均分变化趋势 134 | "trend": 135 | { 136 | //年度列表 137 | years:["2018","2019","2020"], 138 | term1:[6,3,4], 139 | term2:[4,5,2] 140 | } 141 | 142 | 143 | 144 | } -------------------------------------------------------------------------------- /test/test.py: -------------------------------------------------------------------------------- 1 | from flask import jsonify 2 | from flask import Flask,request 3 | from SQL_All import db 4 | # 5 | from CreateUser.models import db as db2 6 | app=Flask(__name__) 7 | app.config['JSON_AS_ASCII'] = False 8 | app.config['SQLALCHEMY_TRACK_MODIFICATIONS']=False 9 | app.config['SQLALCHEMY_DATABASE_URI']="mysql+pymysql://root:root@127.0.0.1:3306/GK_ZH" 10 | db2.init_app(app) 11 | @app.route('/banji', methods=['GET']) 12 | def banji(): 13 | if request.method=='GET': 14 | class_name=request.args.get('class_name') 15 | semester=request.args.get('semester') 16 | year=request.args.get('year') 17 | "127.0.0.1:5000:/banji?class_name=17dashuju&semester=d&year=" 18 | 19 | #if class_name=='17云计算1' : 20 | 21 | #1-- 22 | people='select count(distinct style_id) from bigdata where gk_class="{}";'.format(class_name) 23 | db.execute(people) 24 | students_num=db.fetchone()[0] 25 | classjbCard={ 26 | "classname": class_name, 27 | "students": students_num 28 | } 29 | 30 | #2-- 31 | #if semester=='第一学期': 32 | one_zh_score='select avg(zh_score) from bigdata where gk_class="{}" and semester="第一学期";'.format(class_name) 33 | db.execute(one_zh_score) 34 | term1_score=db.fetchone()[0] 35 | 36 | 37 | #one_zh_rank='select s.gk_class,s.semester,s.zh,(select count(distinct zh) from (select avg(zh_score) as zh from bigdata group by gk_class)as a where zh>=s.zh)as rank from (select semester,gk_class,avg(zh_score) as zh from bigdata group by gk_class,semester)as s where gk_class="{}" and semester="第一学期" order by s.zh desc;'.format(class_name) 38 | one_zh_rank = 'select s.year,s.semester,s.gk_class,s.zh,' \ 39 | 'count(distinct a.zh) from (select year,semester,gk_class,avg(zh_score) as zh ' \ 40 | 'from bigdata where year="{}" and semester="第一学期" group by gk_class,year )as s ' \ 41 | 'join (select year,gk_class,avg(zh_score) as zh from bigdata where year="{}" and semester="第一学期" ' \ 42 | 'group by gk_class,year) as a on s.zh <= a.zh where s.gk_class="{}" and s.year="{}" ' \ 43 | 'group by s.gk_class,s.year order by s.zh desc;'.format(year,year,class_name,year) 44 | 45 | db.execute(one_zh_rank) 46 | term1_paiming=db.fetchall()[0] 47 | 48 | 49 | #第二学期 50 | two_zh_score = 'select avg(zh_score) from bigdata where gk_class="{}" and semester="第二学期";'.format(class_name) 51 | db.execute(two_zh_score) 52 | term2_score = db.fetchone()[0] 53 | 54 | 55 | two_zh_rank = 'select s.year,s.semester,s.gk_class,s.zh,' \ 56 | 'count(distinct a.zh) from (select year,semester,gk_class,avg(zh_score) as zh ' \ 57 | 'from bigdata where year="{}" and semester="第二学期" group by gk_class,year )as s ' \ 58 | 'join (select year,gk_class,avg(zh_score) as zh from bigdata where year="{}" and semester="第二学期" ' \ 59 | 'group by gk_class,year) as a on s.zh <= a.zh where s.gk_class="{}" and s.year="{}" ' \ 60 | 'group by s.gk_class,s.year order by s.zh desc;'.format(year, year, class_name, year) 61 | print(two_zh_rank) 62 | db.execute(two_zh_rank) 63 | term2_paiming = db.fetchall()[0] 64 | 65 | classCard = { 66 | "term1_score": term1_score, # 第一学期的综合素平均分 67 | "term2_score":term2_score, #第二学期的综合素平均分 68 | "term1_paiming": term1_paiming, # 第一学期在全院的排名 69 | "term2_paiming":term2_paiming #第二学期在全院的排名 70 | # https://blog.csdn.net/shiwodecuo/article/details/54632839 71 | #https://blog.csdn.net/qq1032350287/article/details/86693068 72 | } 73 | 74 | 75 | ''' 76 | 你搞定 77 | 78 | ''' 79 | #3--- 80 | #整个年度,不管学期 81 | grade = "20" + class_name[:2] 82 | if semester == "year" : 83 | college_value='select avg(political_edu),avg(physical_heal),avg(innovation_entrep),avg(technical_skills),avg(volunte),avg(human_art),avg(zh_theory) from bigdata WHERE year="{}" AND grade="{}";'.format(year,grade) 84 | class_value = 'select avg(political_edu),avg(physical_heal),avg(innovation_entrep),avg(technical_skills),avg(volunte),avg(human_art),avg(zh_theory) from bigdata WHERE gk_class="{}" AND year="{}";'.format(class_name,year) 85 | 86 | #传入学期 87 | else: 88 | college_value = 'select avg(political_edu),avg(physical_heal),avg(innovation_entrep),avg(technical_skills),avg(volunte),avg(human_art),avg(zh_theory) from bigdata WHERE grade="{}" AND semester="{}" AND year="{}";'.format(grade, semester,year) 89 | class_value = 'select avg(political_edu),avg(physical_heal),avg(innovation_entrep),avg(technical_skills),avg(volunte),avg(human_art),avg(zh_theory) from bigdata WHERE gk_class="{}" AND semester="{}" AND year="{}";'.format(class_name,semester,year) 90 | 91 | 92 | db.execute(college_value) 93 | CollegeValue=db.fetchall()[0] 94 | 95 | db.execute(class_value) 96 | ClassValue = db.fetchall()[0] 97 | 98 | 99 | suchindexscores= { 100 | "CollegeValue": CollegeValue, 101 | "ClassValue": ClassValue 102 | }, 103 | 104 | 105 | #4--- 106 | student_name=' select stu_name from bigdata where gk_class="{}" and semester="第二学期" and year="{}";'.format(class_name,year) 107 | stu_name_app=[] 108 | db.execute(student_name) 109 | StudentName=db.fetchall() 110 | for stuName in StudentName: 111 | stu_name_app.append(stuName[0]) 112 | students={ 113 | "student":stu_name_app 114 | } 115 | 116 | 117 | #5--- 118 | indexs = {'political_edu': '思想政治', 'physical_heal': "身心健康", 'innovation_entrep': '创新创业', 119 | 'technical_skills': '技术技能', 'volunte': '志愿服务', 'human_art': '人文艺术', 'zh_theory': '综合素质理论'} 120 | 121 | topstudent={} 122 | for key, value in indexs.items(): 123 | name_app=[] 124 | score_app=[] 125 | all_sql='select stu_name,{} from bigdata where gk_class="{}" and semester="{}" and year="{}" order by {} desc limit 5;'.format(key,class_name,semester,year,key) 126 | db.execute(all_sql) 127 | allName=db.fetchall() 128 | 129 | for name,score in allName: 130 | name_app.append(name) 131 | score_app.append(score) 132 | 133 | topstudent[value] = { 134 | 'names':name_app , 135 | 'scores': score_app 136 | } 137 | 138 | #6- 139 | total_sql='select count(stu_name),CASE ' \ 140 | 'when score >= 0 and score <= 10 THEN "0-10" ' \ 141 | 'when score > 10 and score <= 20 THEN "11-20" ' \ 142 | 'when score > 20 and score <= 30 THEN "21-30" ' \ 143 | 'when score > 30 and score <= 40 THEN "31-40" ' \ 144 | 'when score > 40 and score <=50 THEN "41-50" ' \ 145 | 'when score>50 THEN "50以上" end as "总分区间" from bigdata ' \ 146 | 'where gk_class="{}" and semester="{}" and year="{}" ' \ 147 | 'group by CASE when score >= 0 and score <= 10 THEN "0-10" ' \ 148 | 'when score > 10 and score <= 20 THEN "11-20" ' \ 149 | 'when score > 20 and score <= 30 THEN "21-30" ' \ 150 | 'when score > 30 and score <= 40 THEN "31-40" ' \ 151 | 'when score > 40 and score <=50 THEN "41-50" ' \ 152 | 'when score>50 THEN "50以上" end ' \ 153 | 'order by CASE when score >= 0 and score <= 10 THEN "0-10" ' \ 154 | 'when score > 10 and score <= 20 THEN "11-20" ' \ 155 | 'when score > 20 and score <= 30 THEN "21-30" ' \ 156 | 'when score > 30 and score <= 40 THEN "31-40" ' \ 157 | 'when score > 40 and score <=50 THEN "41-50" ' \ 158 | 'when score>50 THEN "50以上" end;'.format(class_name,semester,year) 159 | 160 | db.execute(total_sql) 161 | TotalScores = db.fetchall() 162 | print(TotalScores) 163 | allscores=[] 164 | total_app=[] 165 | 166 | for people,total in TotalScores: 167 | total_score = {} 168 | total_score['value']=people 169 | total_score['name']=total 170 | allscores.append(total_score) 171 | 172 | total_app.append(total) 173 | print(allscores) 174 | 175 | totalscores={ 176 | "ranges":total_app, 177 | "allscores":allscores 178 | } 179 | 180 | 181 | return jsonify({"ClassData": classjbCard, "classCard": classCard,"suchindexscores":suchindexscores,"student":students,"tostudent":topstudent,"totalscores":totalscores}) 182 | 183 | # elif semester=='第二学期': 184 | # one_zh_score = 'select avg(zh_score) from bigdata where gk_class="{}" and semester="{}";'.format(class_name, semester) 185 | # db.execute(one_zh_score) 186 | # term1_score = db.fetchone()[0] 187 | # classCard={ 188 | # "term1_score": term1_score, #第一学期的综合素平均分 189 | # "term2_score": 1, #第二学期的综合素平均分 190 | # "term1_paiming": 9, #第一学期在全院的排名 191 | # "term2_paiming": 6 #第二学期在全院的排名 192 | # } 193 | # 194 | # print(classjbCard) 195 | # return jsonify({"ClassData":classjbCard,"classCard":classCard}) 196 | 197 | 198 | @app.route('/geren', methods=['GET']) 199 | def geren(): 200 | if request.method=='GET': 201 | semester = request.args.get('semester') 202 | year = request.args.get('year') 203 | stu_name = request.args.get('stu_id') 204 | class_name = request.args.get('class_name') 205 | 206 | print(stu_name) 207 | # 1-- 208 | stu_score = 'select zh_score from bigdata where stu_name="{}" and semester="第一学期" and year="{}";'.format(stu_name, year) 209 | print(stu_score) 210 | db.execute(stu_score) 211 | 212 | term1_avlscore = db.fetchall()[0] 213 | print(term1_avlscore) 214 | stu_yuan_rank = 'select (select count(distinct zh) from (select zh_score as zh from bigdata where semester="第一学期" and year="{}") as a where zh>=s.zh) as "rank" from (select stu_name,zh_score as zh from bigdata where semester="第一学期" and year="{}") as s where stu_name="{}" order by s.zh desc;'.format( 215 | year, year, stu_name) 216 | db.execute(stu_yuan_rank) 217 | term1_yranking = db.fetchone()[0] 218 | stu_class_rank = 'select (select count(distinct zh) from (select zh_score as zh from bigdata where gk_class="{}" and semester="第一学期" and year="{}") as a where zh>=s.zh) as "rank" from (select stu_name,zh_score as zh from bigdata where gk_class="{}" and semester="第一学期" and year="{}") as s where stu_name="{}" order by s.zh desc;'.format( 219 | class_name, year, class_name, year, stu_name) 220 | db.execute(stu_class_rank) 221 | term1_cranking = db.fetchone()[0] 222 | studentCard1 = { 223 | "term1_avlscore": term1_avlscore, ##第一学期综合素质平均分 224 | "term1_yranking": term1_yranking, ##第一学期综合素质在全院排名 225 | "term1_cranking": term1_cranking ##第一学期综合素质在全班排名 226 | } 227 | 228 | # 1_1-- 229 | stu_score_2 = 'select avg(political_edu),avg(physical_heal),avg(innovation_entrep),avg(technical_skills),avg(volunte),avg(human_art),avg(zh_theory) from bigdata where stu_name="{}" and semester="第二学期" and year="{}";'.format( 230 | stu_name, year) 231 | db.execute(stu_score_2) 232 | term2_avlscore = db.fetchall()[0] 233 | stu_yuan_rank_2 = 'select (select count(distinct zh) from (select zh_score as zh from bigdata where semester="第二学期" and year="{}") as a where zh>=s.zh) as "rank" from (select stu_name,zh_score as zh from bigdata where semester="第二学期" and year="{}") as s where stu_name="{}" order by s.zh desc;'.format( 234 | year, year, stu_name) 235 | db.execute(stu_yuan_rank_2) 236 | term2_yranking = db.fetchone()[0] 237 | stu_class_rank_2 = 'select (select count(distinct zh) from (select zh_score as zh from bigdata where gk_class="{}" and semester="第二学期" and year="{}") as a where zh>=s.zh) as "rank" from (select stu_name,zh_score as zh from bigdata where gk_class="{}" and semester="第二学期" and year="{}") as s where stu_name="{}" order by s.zh desc;'.format( 238 | class_name, year, class_name, year, stu_name) 239 | db.execute(stu_class_rank_2) 240 | term2_cranking = db.fetchone()[0] 241 | studentCard2 = { 242 | "term2_avlscore": term2_avlscore, ##第二学期综合素质平均分 243 | "term2_yranking": term2_yranking, ##第二学期综合素质在全院排名 244 | "term2_cranking": term2_cranking ##第二学期综合素质在全班排名 245 | } 246 | 247 | # 2-- 248 | stu_zhibiao_score = db2.session.execute( 249 | 'select political_edu,physical_heal,innovation_entrep,technical_skills,volunte,human_art,zh_theory from bigdata where stu_name="{}" and year="{}" and semester="{}";'.format( 250 | stu_name, year, semester)).fetchone() 251 | class_zhibiao_avg_score = db2.session.execute( 252 | 'select avg(political_edu),avg(physical_heal),avg(innovation_entrep),avg(technical_skills),avg(volunte),avg(human_art),avg(zh_theory) from bigdata where gk_class="{}" and year="{}" and semester="{}";'.format( 253 | class_name, year, semester)) 254 | yuan_zhibiao_avg_score = db2.session.execute( 255 | 'select avg(political_edu),avg(physical_heal),avg(innovation_entrep),avg(technical_skills),avg(volunte),avg(human_art),avg(zh_theory) from bigdata where year="{}" and semester="{}";'.format( 256 | year, semester)) 257 | suchscores = [] 258 | suchscores2 = [] 259 | suchscores3 = [] 260 | name1 = '学院指标平均分' 261 | name2 = '班级指标平均分' 262 | name3 = '学生指标分数' 263 | for i in stu_zhibiao_score: 264 | suchscores.append(i) 265 | for i_1 in class_zhibiao_avg_score: 266 | suchscores2.append(i_1) 267 | for i_2 in yuan_zhibiao_avg_score: 268 | suchscores3.append(i_2) 269 | 270 | suchindex = { 271 | 'suchindexscores': [{ 272 | 'value': list(suchscores3[0].itervalues()), 273 | 'name': name1 274 | }, { 275 | 'value': list(suchscores2[0].itervalues()), 276 | 'name': name2 277 | }, { 278 | 'value': suchscores, 279 | 'name': name3 280 | } 281 | ] 282 | } ##各指标雷达 283 | 284 | # 3-- 285 | indexs = {'political_edu': '思想政治', 'physical_heal': "身心健康", 'innovation_entrep': '创新创业', 286 | 'technical_skills': '技术技能', 'volunte': '志愿服务', 'human_art': '人文艺术', 'zh_theory': '综合素质理论'} 287 | yuanData = [] 288 | ClassData = [] 289 | for key, value in indexs.items(): 290 | score = db2.session.execute( 291 | 'select {} from bigdata where stu_name="{}" and year="{}" and semester="{}";'.format(key, 292 | stu_name, 293 | year, 294 | semester)).fetchone() 295 | rank = db2.session.execute( 296 | 'select (select count(distinct zh) from (select {} as zh from bigdata where year="{}" and semester="{}") as a where zh>=s.zh) as "rank" from (select stu_name,{} as zh from bigdata where year="{}" and semester="{}") as s where stu_name="{}" order by s.zh desc;'.format( 297 | key, year, semester, key, year, semester, stu_name)).fetchone() 298 | yuanData.append({ 299 | 'Collegindex': value, 300 | 'Collegscores': score[0], 301 | 'Collegranking': rank[0] 302 | }) 303 | for key1, value1 in indexs.items(): 304 | score1 = db2.session.execute( 305 | 'select {} from bigdata where stu_name="{}" and year="{}" and semester="{}";'.format(key1, stu_name, 306 | year, 307 | semester)).fetchone() 308 | rank1 = db2.session.execute( 309 | 'select (select count(distinct zh) from (select {} as zh from bigdata where gk_class="{}" and year="{}" and semester="{}") as a where zh>=s.zh) as "rank" from (select stu_name,{} as zh from bigdata where gk_class="{}" and year="{}" and semester="{}") as s where stu_name="{}" order by s.zh desc;'.format( 310 | key1, class_name, year, semester, key1, class_name, year, semester, stu_name)).fetchone() 311 | ClassData.append({ 312 | 'Classindex': value1, 313 | 'Classscores': score1[0], 314 | 'Classranking': rank1[0] 315 | }) 316 | data1 = { 317 | 'CollegeData': yuanData # 各指标在全院排名和各指标分数 318 | } 319 | data2 = { 320 | 'ClassData': ClassData # 各指标在全班排名和各指标分数 321 | } 322 | 323 | return jsonify( 324 | {"studentCard1": studentCard1, "studentCard2": studentCard2, "suchindex": suchindex, "data1": data1, 325 | "data2": data2}) 326 | 327 | if __name__ == '__main__': 328 | app.run(debug=True) 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | -------------------------------------------------------------------------------- /test/testUpload.py: -------------------------------------------------------------------------------- 1 | import os 2 | from flask import Blueprint, jsonify, request, flash, redirect 3 | from werkzeug.utils import secure_filename 4 | from flask import Flask 5 | from logging import getLogger 6 | 7 | logger=getLogger() 8 | 9 | dangqian=os.path.dirname(os.path.dirname(__file__)) 10 | 11 | UPLOAD_PATH=dangqian+'/uploads/static/' 12 | 13 | ALLOWED_EXTENSIONS = ['xls', 'xlsx','csv'] 14 | 15 | app = Flask(__name__) 16 | 17 | def allowed_file(filename): 18 | return '.' in filename and filename.rsplit('.',1)[1] in ALLOWED_EXTENSIONS 19 | 20 | # http://flask.pocoo.org/docs/0.12/patterns/fileuploads/ 21 | @app.route('/upload', methods=['POST']) 22 | def upload_file(): 23 | if request.method == 'POST': 24 | # check if the post request has the file part 25 | if 'file' not in request.files: 26 | return jsonify({'code': -1, 'filename': '', 'msg': 'No file part'}) 27 | 28 | file = request.files['file'] 29 | # if user does not select file, browser also submit a empty part without filename 30 | if file.filename == '': 31 | logger.debug('No selected file') 32 | return jsonify({'code': -1, 'filename': '', 'msg': 'No selected file'}) 33 | else: 34 | try: 35 | if file and allowed_file(file.filename): 36 | origin_file_name = file.filename 37 | logger.debug('filename is %s' % origin_file_name) 38 | # filename = secure_filename(file.filename) 39 | filename = origin_file_name 40 | 41 | if os.path.exists(UPLOAD_PATH): 42 | logger.debug('%s path exist' % UPLOAD_PATH) 43 | pass 44 | else: 45 | logger.debug('%s path not exist, do make dir' % UPLOAD_PATH) 46 | os.makedirs(UPLOAD_PATH) 47 | print(UPLOAD_PATH) 48 | file.save(os.path.join(UPLOAD_PATH, filename)) 49 | print(file) 50 | logger.debug('%s save successfully' % filename) 51 | return jsonify({'code': 0, 'filename': origin_file_name, 'msg': ''}) 52 | else: 53 | logger.debug('%s not allowed' % file.filename) 54 | return jsonify({'code': -1, 'filename': '', 'msg': 'File not allowed'}) 55 | except Exception as e: 56 | logger.debug('upload file exception: %s' % e) 57 | return jsonify({'code': -1, 'filename': '', 'msg': 'Error occurred'}) 58 | else: 59 | return jsonify({'code': -1, 'filename': '', 'msg': 'Method not allowed'}) 60 | 61 | @app.route('/delete', methods=['GET','POST']) 62 | def delete_file(): 63 | if request.method == 'GET': 64 | filenames = request.args.get('filename') 65 | print(filenames) 66 | #timestamp = request.args.get('timestamp') 67 | #logger.debug('delete file : %s, timestamp is %s' % (filename, timestamp)) 68 | try: 69 | fullfile = os.path.join(UPLOAD_PATH, filenames) 70 | 71 | if os.path.exists(fullfile): 72 | os.remove(fullfile) 73 | logger.debug("%s removed successfully" % fullfile) 74 | return jsonify({'code': 0, 'msg': ''}) 75 | else: 76 | return jsonify({'code': -1, 'msg': 'File not exist'}) 77 | 78 | except Exception as e: 79 | logger.debug("delete file error %s" % e) 80 | return jsonify({'code': -1, 'msg': 'File deleted error'}) 81 | 82 | else: 83 | return jsonify({'code': -1, 'msg': 'Method not allowed'}) 84 | 85 | if __name__ == '__main__': 86 | app.run(debug=True) -------------------------------------------------------------------------------- /test/testsql.py: -------------------------------------------------------------------------------- 1 | from flask import jsonify, request 2 | from . import db 3 | from . import select 4 | from CreateUser.models import db as db2 5 | 6 | 7 | # 班级图所需要的数据 8 | 9 | @select.route('/banji', methods=['POST']) 10 | # @login_required 11 | def banji(): 12 | if request.method == 'POST': 13 | formdata = request.json 14 | print(formdata) 15 | class_name = formdata['classid'] 16 | semester = formdata['term'] 17 | 18 | if formdata['term'] == "term1": 19 | semester = "第一学期" 20 | elif formdata['term'] == "term2": 21 | semester = "第二学期" 22 | 23 | year = formdata.get('year') 24 | # college=formdata.get('college') 25 | 26 | filter_str = '' 27 | if semester == 'year': 28 | filter_str = 'and year="{}"'.format(year) 29 | else: 30 | filter_str = 'and semester="{}" and year="{}"'.format(semester, year) 31 | "127.0.0.1:5000:/banji?class_name=17dashuju&semester=d&year=2018&college=大数据与人工智能" 32 | 33 | # if class_name=='17云计算1' : 34 | 35 | # 1-- 36 | people = 'select count(distinct style_id) from bigdata where gk_class="{}";'.format(class_name) 37 | print(people) 38 | db.execute(people) 39 | students_num = db.fetchone()[0] 40 | classjbCard = { 41 | "classname": class_name, 42 | "students": students_num 43 | } 44 | 45 | # 2-- 46 | # if semester=='第一学期': 47 | one_zh_score = 'select avg(zh_score) from bigdata where gk_class="{}" and semester="第一学期";'.format(class_name) 48 | db.execute(one_zh_score) 49 | term1_score = db.fetchone()[0] 50 | 51 | # one_zh_rank='select s.gk_class,s.semester,s.zh,(select count(distinct zh) from (select avg(zh_score) as zh from bigdata group by gk_class)as a where zh>=s.zh)as rank from (select semester,gk_class,avg(zh_score) as zh from bigdata group by gk_class,semester)as s where gk_class="{}" and semester="第一学期" order by s.zh desc;'.format(class_name) 52 | one_zh_rank = 'select s.year,s.semester,s.gk_class,s.zh,' \ 53 | 'count(distinct a.zh) from (select year,semester,gk_class,avg(zh_score) as zh ' \ 54 | 'from bigdata where year="{}" and semester="第一学期" group by gk_class,year )as s ' \ 55 | 'join (select year,gk_class,avg(zh_score) as zh from bigdata where year="{}" and semester="第一学期" ' \ 56 | 'group by gk_class,year) as a on s.zh <= a.zh where s.gk_class="{}" and s.year="{}" ' \ 57 | 'group by s.gk_class,s.year order by s.zh desc;'.format(year, year, class_name, year) 58 | 59 | db.execute(one_zh_rank) 60 | term1_paiming = db.fetchall()[0] 61 | 62 | # 第二学期 63 | two_zh_score = 'select avg(zh_score) from bigdata where gk_class="{}" and semester="第二学期";'.format(class_name) 64 | db.execute(two_zh_score) 65 | term2_score = db.fetchone()[0] 66 | 67 | two_zh_rank = 'select s.year,s.semester,s.gk_class,s.zh,' \ 68 | 'count(distinct a.zh) from (select year,semester,gk_class,avg(zh_score) as zh ' \ 69 | 'from bigdata where year="{}" and semester="第二学期" group by gk_class,year )as s ' \ 70 | 'join (select year,gk_class,avg(zh_score) as zh from bigdata where year="{}" and semester="第二学期" ' \ 71 | 'group by gk_class,year) as a on s.zh <= a.zh where s.gk_class="{}" and s.year="{}" ' \ 72 | 'group by s.gk_class,s.year order by s.zh desc;'.format(year, year, class_name, year) 73 | print(two_zh_rank) 74 | db.execute(two_zh_rank) 75 | term2_paiming = db.fetchall()[0] 76 | 77 | classCard = { 78 | "term1_score": term1_score, # 第一学期的综合素平均分 79 | "term2_score": term2_score, # 第二学期的综合素平均分 80 | "term1_paiming": term1_paiming, # 第一学期在全院的排名 81 | "term2_paiming": term2_paiming # 第二学期在全院的排名 82 | # https://blog.csdn.net/shiwodecuo/article/details/54632839 83 | # https://blog.csdn.net/qq1032350287/article/details/86693068 84 | } 85 | 86 | # 3--- 87 | # 整个年度,不管学期 88 | grade = "20" + class_name[:2] 89 | 90 | college_value = 'select avg(political_edu),avg(physical_heal),avg(innovation_entrep),avg(technical_skills),avg(volunte),avg(human_art),avg(zh_theory) from bigdata WHERE grade="{}" {};'.format( 91 | grade, filter_str) 92 | class_value = 'select avg(political_edu),avg(physical_heal),avg(innovation_entrep),avg(technical_skills),avg(volunte),avg(human_art),avg(zh_theory) from bigdata WHERE gk_class="{}" {};'.format( 93 | class_name, filter_str) 94 | 95 | db.execute(college_value) 96 | CollegeValue = db.fetchall()[0] 97 | 98 | db.execute(class_value) 99 | ClassValue = db.fetchall()[0] 100 | 101 | suchindexscores = [ 102 | { 103 | 'value': CollegeValue, 'name': '学院指标平均分' 104 | }, 105 | { 106 | 'value': ClassValue, 'name': '班级指标平均分' 107 | }] 108 | 109 | # 4--- 110 | student_name = ' select stu_name from bigdata where gk_class="{}" and semester="第二学期" and year="{}";'.format( 111 | class_name, year) 112 | stu_name_app = [] 113 | db.execute(student_name) 114 | StudentName = db.fetchall() 115 | for stuName in StudentName: 116 | stu_name_app.append(stuName[0]) 117 | students = { 118 | "student": stu_name_app 119 | } 120 | 121 | # 5--- 122 | indexs = {'political_edu': '思想政治', 'physical_heal': "身心健康", 'innovation_entrep': '创新创业', 123 | 'technical_skills': '技术技能', 'volunte': '志愿服务', 'human_art': '人文艺术', 'zh_theory': '综合素质理论', 124 | 'zh_score': "总分Top5"} 125 | 126 | topstudent = {} 127 | for key, value in indexs.items(): 128 | name_app = [] 129 | score_app = [] 130 | all_sql = 'select stu_name,{} from bigdata where gk_class="{}" {filter_str} order by {} desc limit 5;'.format( 131 | key, class_name, key, filter_str=filter_str) 132 | db.execute(all_sql) 133 | allName = db.fetchall() 134 | 135 | for name, score in allName: 136 | name_app.append(name) 137 | score_app.append(score) 138 | 139 | topstudent[value] = { 140 | 'names': name_app, 141 | 'scores': score_app 142 | } 143 | 144 | # 6- 145 | total_sql = 'select count(stu_name),CASE ' \ 146 | 'when score >= 0 and score <= 10 THEN "0-10" ' \ 147 | 'when score > 10 and score <= 20 THEN "11-20" ' \ 148 | 'when score > 20 and score <= 30 THEN "21-30" ' \ 149 | 'when score > 30 and score <= 40 THEN "31-40" ' \ 150 | 'when score > 40 and score <=50 THEN "41-50" ' \ 151 | 'when score>50 THEN "50以上" end as "总分区间" from bigdata ' \ 152 | 'where gk_class="{}" {filter_str} ' \ 153 | 'group by CASE when score >= 0 and score <= 10 THEN "0-10" ' \ 154 | 'when score > 10 and score <= 20 THEN "11-20" ' \ 155 | 'when score > 20 and score <= 30 THEN "21-30" ' \ 156 | 'when score > 30 and score <= 40 THEN "31-40" ' \ 157 | 'when score > 40 and score <=50 THEN "41-50" ' \ 158 | 'when score>50 THEN "50以上" end ' \ 159 | 'order by CASE when score >= 0 and score <= 10 THEN "0-10" ' \ 160 | 'when score > 10 and score <= 20 THEN "11-20" ' \ 161 | 'when score > 20 and score <= 30 THEN "21-30" ' \ 162 | 'when score > 30 and score <= 40 THEN "31-40" ' \ 163 | 'when score > 40 and score <=50 THEN "41-50" ' \ 164 | 'when score>50 THEN "50以上" end;'.format(class_name, filter_str=filter_str) 165 | 166 | db.execute(total_sql) 167 | TotalScores = db.fetchall() 168 | allscores = [] 169 | total_app = [] 170 | for people, total in TotalScores: 171 | total_score = {} 172 | total_score['value'] = people 173 | total_score['name'] = total 174 | allscores.append(total_score) 175 | total_app.append(total) 176 | 177 | totalscores = { 178 | "ranges": total_app, 179 | "allscores": allscores 180 | } 181 | 182 | return jsonify( 183 | {"classjbCard": classjbCard, "classCard": classCard, "suchindexscores": suchindexscores, 184 | "students": students, 185 | "topstudent": topstudent, "totalscores": totalscores}) 186 | 187 | 188 | @select.route('/geren', methods=['POST']) 189 | # @login_required 190 | def geren(): 191 | if request.method == 'POST': 192 | formdata = request.json 193 | if formdata['term'] == "term1": 194 | semester = "第一学期" 195 | elif formdata['term'] == "term2": 196 | semester = "第二学期" 197 | 198 | year = formdata.get('year') 199 | stu_name = formdata.get('stu_id') 200 | class_name = formdata.get('classid') 201 | 202 | print(stu_name) 203 | # 1-- 204 | stu_score = 'select zh_score from bigdata where stu_name="{}" and semester="第一学期" and year="{}";'.format( 205 | stu_name, year) 206 | print(stu_score) 207 | db.execute(stu_score) 208 | 209 | term1_avlscore = db.fetchall()[0][0] 210 | print(term1_avlscore) 211 | stu_yuan_rank = 'select (select count(distinct zh) from (select zh_score as zh from bigdata where semester="第一学期" and year="{}") as a where zh>=s.zh) as "rank" from (select stu_name,zh_score as zh from bigdata where semester="第一学期" and year="{}") as s where stu_name="{}" order by s.zh desc;'.format( 212 | year, year, stu_name) 213 | db.execute(stu_yuan_rank) 214 | term1_yranking = db.fetchone()[0] 215 | stu_class_rank = 'select (select count(distinct zh) from (select zh_score as zh from bigdata where gk_class="{}" and semester="第一学期" and year="{}") as a where zh>=s.zh) as "rank" from (select stu_name,zh_score as zh from bigdata where gk_class="{}" and semester="第一学期" and year="{}") as s where stu_name="{}" order by s.zh desc;'.format( 216 | class_name, year, class_name, year, stu_name) 217 | db.execute(stu_class_rank) 218 | term1_cranking = db.fetchone()[0] 219 | studentCard1 = { 220 | "term1_avlscore": term1_avlscore, ##第一学期综合素质平均分 221 | "term1_yranking": term1_yranking, ##第一学期综合素质在全院排名 222 | "term1_cranking": term1_cranking ##第一学期综合素质在全班排名 223 | } 224 | 225 | # 1_1-- 226 | stu_score_2 = 'select zh_score from bigdata where stu_name="{}" and semester="第二学期" and year="{}";'.format( 227 | stu_name, year) 228 | db.execute(stu_score_2) 229 | term2_avlscore = db.fetchall()[0][0] 230 | stu_yuan_rank_2 = 'select (select count(distinct zh) from (select zh_score as zh from bigdata where semester="第二学期" and year="{}") as a where zh>=s.zh) as "rank" from (select stu_name,zh_score as zh from bigdata where semester="第二学期" and year="{}") as s where stu_name="{}" order by s.zh desc;'.format( 231 | year, year, stu_name) 232 | db.execute(stu_yuan_rank_2) 233 | term2_yranking = db.fetchone()[0] 234 | stu_class_rank_2 = 'select (select count(distinct zh) from (select zh_score as zh from bigdata where gk_class="{}" and semester="第二学期" and year="{}") as a where zh>=s.zh) as "rank" from (select stu_name,zh_score as zh from bigdata where gk_class="{}" and semester="第二学期" and year="{}") as s where stu_name="{}" order by s.zh desc;'.format( 235 | class_name, year, class_name, year, stu_name) 236 | db.execute(stu_class_rank_2) 237 | term2_cranking = db.fetchone()[0] 238 | studentCard2 = { 239 | "term2_avlscore": term2_avlscore, ##第二学期综合素质平均分 240 | "term2_yranking": term2_yranking, ##第二学期综合素质在全院排名 241 | "term2_cranking": term2_cranking ##第二学期综合素质在全班排名 242 | } 243 | 244 | # 2-- 245 | stu_zhibiao_score = db2.session.execute( 246 | 'select political_edu,physical_heal,innovation_entrep,technical_skills,volunte,human_art,zh_theory from bigdata where stu_name="{}" and year="{}" and semester="{}";'.format( 247 | stu_name, year, semester)).fetchone() 248 | print("学生指标sql:", 249 | 'select political_edu,physical_heal,innovation_entrep,technical_skills,volunte,human_art,zh_theory from bigdata where stu_name="{}" and year="{}" and semester="{}";'.format( 250 | stu_name, year, semester)) 251 | class_zhibiao_avg_score = db2.session.execute( 252 | 'select avg(political_edu),avg(physical_heal),avg(innovation_entrep),avg(technical_skills),avg(volunte),avg(human_art),avg(zh_theory) from bigdata where gk_class="{}" and year="{}" and semester="{}";'.format( 253 | class_name, year, semester)) 254 | yuan_zhibiao_avg_score = db2.session.execute( 255 | 'select avg(political_edu),avg(physical_heal),avg(innovation_entrep),avg(technical_skills),avg(volunte),avg(human_art),avg(zh_theory) from bigdata where year="{}" and semester="{}";'.format( 256 | year, semester)) 257 | suchscores = [] 258 | suchscores2 = [] 259 | suchscores3 = [] 260 | name1 = '学院指标平均分' 261 | name2 = '班级指标平均分' 262 | name3 = '学生指标分数' 263 | for i in stu_zhibiao_score: 264 | suchscores.append(i) 265 | for i_1 in class_zhibiao_avg_score: 266 | suchscores2.append(i_1) 267 | for i_2 in yuan_zhibiao_avg_score: 268 | suchscores3.append(i_2) 269 | 270 | suchindex = [{ 271 | 'value': list(suchscores3[0].itervalues()), 272 | 'name': name1 273 | }, { 274 | 'value': list(suchscores2[0].itervalues()), 275 | 'name': name2 276 | }, { 277 | 'value': suchscores, 278 | 'name': name3 279 | } 280 | ] 281 | ##各指标雷达 282 | 283 | # 3-- 284 | indexs = {'political_edu': '思想政治', 'physical_heal': "身心健康", 'innovation_entrep': '创新创业', 285 | 'technical_skills': '技术技能', 'volunte': '志愿服务', 'human_art': '人文艺术', 'zh_theory': '综合素质理论'} 286 | yuanData = [] 287 | ClassData = [] 288 | for key, value in indexs.items(): 289 | score = db2.session.execute( 290 | 'select {} from bigdata where stu_name="{}" and year="{}" and semester="{}";'.format(key, 291 | stu_name, 292 | year, 293 | semester)).fetchone() 294 | rank = db2.session.execute( 295 | 'select (select count(distinct zh) from (select {} as zh from bigdata where year="{}" and semester="{}") as a where zh>=s.zh) as "rank" from (select stu_name,{} as zh from bigdata where year="{}" and semester="{}") as s where stu_name="{}" order by s.zh desc;'.format( 296 | key, year, semester, key, year, semester, stu_name)).fetchone() 297 | yuanData.append({ 298 | 'Collegindex': value, 299 | 'Collegscores': score[0], 300 | 'Collegranking': rank[0] 301 | }) 302 | for key1, value1 in indexs.items(): 303 | score1 = db2.session.execute( 304 | 'select {} from bigdata where stu_name="{}" and year="{}" and semester="{}";'.format(key1, stu_name, 305 | year, 306 | semester)).fetchone() 307 | rank1 = db2.session.execute( 308 | 'select (select count(distinct zh) from (select {} as zh from bigdata where gk_class="{}" and year="{}" and semester="{}") as a where zh>=s.zh) as "rank" from (select stu_name,{} as zh from bigdata where gk_class="{}" and year="{}" and semester="{}") as s where stu_name="{}" order by s.zh desc;'.format( 309 | key1, class_name, year, semester, key1, class_name, year, semester, stu_name)).fetchone() 310 | ClassData.append({ 311 | 'Classindex': value1, 312 | 'Classscores': score1[0], 313 | 'Classranking': rank1[0] 314 | }) 315 | data1 = { 316 | 'CollegeData': yuanData # 各指标在全院排名和各指标分数 317 | } 318 | data2 = { 319 | 'ClassData': ClassData # 各指标在全班排名和各指标分数 320 | } 321 | 322 | return jsonify( 323 | {"studentCard1": studentCard1, "studentCard2": studentCard2, "suchindexscores": suchindex, "data1": data1, 324 | "data2": data2}) 325 | 326 | 327 | 328 | -------------------------------------------------------------------------------- /testdata/2018-2019学年度第一学期学生综合素质测评分(2017级).xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FormatFa/zhsz_backend/1bcf68fb83f54e8a10874a9e66ef6e04e53685a3/testdata/2018-2019学年度第一学期学生综合素质测评分(2017级).xlsx -------------------------------------------------------------------------------- /testdata/2018-2019学年度第二学期学生综合素质测评分(2017级).xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FormatFa/zhsz_backend/1bcf68fb83f54e8a10874a9e66ef6e04e53685a3/testdata/2018-2019学年度第二学期学生综合素质测评分(2017级).xls -------------------------------------------------------------------------------- /utils/api.py: -------------------------------------------------------------------------------- 1 | from flask import jsonify 2 | def api_result(code,data=None,msg=""): 3 | return jsonify({ 4 | 'code':code, 5 | 'data':data, 6 | 'msg':msg 7 | }) -------------------------------------------------------------------------------- /zhsz_api/__init__.py: -------------------------------------------------------------------------------- 1 | from http.client import HTTPException 2 | from flask import Flask, render_template, jsonify,redirect 3 | from flask_cors import CORS 4 | from settings import config,here 5 | 6 | from .models import db,User 7 | from zhsz_api.controllers import auth 8 | from zhsz_api.extensions import cors,lm,bcrypt,oid 9 | import os 10 | from .controllers import api_blue 11 | 12 | 13 | def create_app(): 14 | 15 | app = Flask( 16 | __name__, 17 | static_folder=os.path.join(here,'dist'), 18 | static_url_path='/' 19 | # template_folder=FRONTEND_FOLD 20 | # ER 21 | ) 22 | print("静态文件夹路径:",os.path.join(here,'dist')) 23 | 24 | app.config['JSON_AS_ASCII'] = False 25 | #app.config['JSONIFY_MIMETYPE'] = "application/json;charset=utf-8" 26 | app.config.from_object(config) 27 | #app的额外扩展 28 | db.init_app(app) 29 | #csrfp.init_app(app) 30 | CORS(app, resources=r'/*') 31 | bcrypt.init_app(app) 32 | oid.init_app(app) 33 | lm.init_app(app) 34 | 35 | @lm.user_loader 36 | def load_user(uid): 37 | return User.query.get(uid) 38 | 39 | @app.route('/') 40 | def index(): 41 | return redirect("index.html") 42 | 43 | #测试 44 | # @app.errorhandler(404) 45 | # def page_not_found(error): 46 | # return render_template('index.html'),404 47 | 48 | #注册登录注册的蓝图 49 | app.register_blueprint(api_blue) 50 | # print("前端地址: http://127.0.0.1:5000/index.html") 51 | 52 | return app 53 | 54 | 55 | def register_error_handlers(app): 56 | @app.errorhandler(HTTPException) 57 | def handle_http_error(exc): 58 | return jsonify({'status': 'error', 'description': exc.description}), exc.code 59 | -------------------------------------------------------------------------------- /zhsz_api/controllers/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import Blueprint 2 | from settings import Config 3 | 4 | db=Config.db 5 | 6 | api_blue = Blueprint('api', __name__, url_prefix='/api') 7 | from . import auth 8 | from . import data 9 | from . import logonav 10 | from .import sql -------------------------------------------------------------------------------- /zhsz_api/controllers/auth.py: -------------------------------------------------------------------------------- 1 | from flask import Blueprint, jsonify, request 2 | from flask_login import current_user, login_user, logout_user 3 | from zhsz_api.models import User, db 4 | from zhsz_api.forms import RegisterForm, LoginForm 5 | from zhsz_api.extensions import bcrypt 6 | from . import api_blue 7 | from utils.api import api_result 8 | 9 | 10 | @api_blue.route('/auth/register', methods=['POST']) 11 | def register(): 12 | user_data = request.get_json() 13 | print(user_data) 14 | form = RegisterForm(data=user_data) 15 | if form.validate(): 16 | user = User(username=user_data['username'], password=user_data['password']) 17 | db.session.add(user) 18 | db.session.commit() 19 | return api_result(0,msg="注册成功") 20 | return api_result(-1,data=form.errors,msg="注册失败") 21 | 22 | 23 | @api_blue.route('/auth/login', methods=['POST']) 24 | def login(): 25 | user_data = request.get_json() 26 | form = LoginForm(data=user_data) 27 | if form.validate(): 28 | user = form.get_user() 29 | login_user(user, remember=form.remember.data) 30 | return api_result(0,msg="登录成功",data=user.to_json()) 31 | 32 | return api_result(-1,msg="登录失败",data=form.errors) 33 | 34 | # 修改密码,为了方便,从下面的路由里提取出来了 35 | def alterPassword(username,password,checkOld=True,old_password=''): 36 | print('修改密码',username,password,old_password) 37 | user = User.query.filter(User.username ==username).first() 38 | if user == None: 39 | return { 40 | 'code':-1, 41 | 'msg':'用户不存在' 42 | } 43 | if checkOld and not bcrypt.check_password_hash(user.password.encode(), old_password): 44 | return { 45 | 'code':-1, 46 | 'msg':'原密码错误' 47 | } 48 | user.password = bcrypt.generate_password_hash(password) 49 | db.session.add(user) 50 | db.session.commit() 51 | return { 52 | 'code':0, 53 | 'msg':'修改成功' 54 | } 55 | 56 | @api_blue.route('/auth/login/alterPassword', methods=['POST']) 57 | def alter(): 58 | formdata = request.json 59 | if len(formdata['password'])<8: 60 | return jsonify({ 61 | 'code': -1, 62 | 'msg': '密码长度至少为8个' 63 | }) 64 | if formdata['password'] != formdata['password2']: 65 | return api_result( 66 | -1, 67 | msg='两个密码不一样' 68 | ) 69 | result = alterPassword( formdata['username'], formdata['password'],checkOld=True,old_password=formdata['old_password'] ) 70 | # 退出登录 71 | logout() 72 | return api_result(result['code'],msg=result['msg']) 73 | 74 | 75 | 76 | @api_blue.route('/auth/session') 77 | def get_session(): 78 | if not current_user.is_authenticated: 79 | return api_result(-1,"用户未登录") 80 | return api_result(0,data= current_user.to_json()) 81 | # jsonify({'status': 'success', 'user': current_user.to_json()}) 82 | 83 | 84 | @api_blue.route('/auth/logout') 85 | def logout(): 86 | logout_user() 87 | return api_result(0,"退出成功") 88 | -------------------------------------------------------------------------------- /zhsz_api/controllers/data.py: -------------------------------------------------------------------------------- 1 | import os 2 | import time 3 | 4 | import pandas as pd 5 | from flask import Blueprint, jsonify, request 6 | from flask_login import login_required 7 | from settings import config, FileConfig 8 | from zhsz_api.models import Bigtable,db 9 | from utils.api import api_result 10 | from . import api_blue 11 | 12 | ALLOWED_EXTENSIONS = ['xls', 'xlsx', 'csv','jpg','png'] 13 | 14 | 15 | CURRENT = os.path.dirname(os.path.dirname(__file__)) 16 | 17 | # 增加目录后面加多一个 / 18 | UPLOAD_PATH = CURRENT + '/uploads/static/' 19 | UPDATA_PATH = CURRENT + '/uploads/updata/' 20 | 21 | #建立数据目录 22 | if not os.path.exists(UPLOAD_PATH): 23 | print("新建上传文件目录:",UPLOAD_PATH,os.makedirs(UPLOAD_PATH)) 24 | if not os.path.exists(UPDATA_PATH): 25 | print("新建解析数据临时目录:",UPDATA_PATH,os.makedirs(UPDATA_PATH)) 26 | 27 | 28 | need_word = FileConfig.need_word 29 | key = FileConfig.key 30 | need_columns = FileConfig.need_columns 31 | engine=config.engine 32 | 33 | print(engine) 34 | 35 | # 允许的名字 36 | def allowed_file(filename): 37 | return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS 38 | 39 | # 上传文件--保存在uploads的static/上 40 | 41 | # 上传文件--保存在uploads的static/上 42 | ''' 43 | 44 | ''' 45 | @api_blue.route('/data/upload', methods=['POST']) 46 | # @login_required 47 | def upload_file(): 48 | if request.method == 'POST': 49 | formdata = request.form 50 | # 检查file参数是否存在,前端请求url : requests.post('http://127.0.0.1:5000/api_blue/upload', files=files) 51 | if 'file' not in request.files: 52 | return api_result(-1,msg="没有上传文件") 53 | 54 | file = request.files['file'] 55 | 56 | # 如果用户没有选择文件,浏览器也会提交一个没有文件名的空零件 57 | if file.filename == '': 58 | return api_result(-1,msg="没有上传文件,文件名为空") 59 | else: 60 | try: 61 | if file and allowed_file(file.filename): 62 | origin_file_name = file.filename 63 | filename = origin_file_name 64 | #加多一个学院 65 | uploadfile,datafile=getuploadpath(formdata) 66 | 67 | print(filename, "保存到:",uploadfile) 68 | # 文件保存路径以及文件名 69 | file.save(uploadfile) 70 | 71 | return api_result(0,msg="上传成功:"+origin_file_name) 72 | else: 73 | return api_result(-1,msg="不允许上传的文件类型") 74 | 75 | except Exception as e: 76 | print(e) 77 | return api_result(-1,msg="上传文件异常:"+str(e)) 78 | else: 79 | return api_result(-1,msg="不允许非POST方法请求") 80 | 81 | 82 | 83 | STATUS_NOUPLOAD = 0 84 | STATUS_NOPARSE = 1 85 | STATUS_DONE = 2 86 | states = { 87 | 0: "未上传", 88 | 1: "未解析", 89 | 2: "解析完成" 90 | } 91 | 92 | # 获取文件状态 93 | def getstate(college, year, grade, term): 94 | 95 | up_path,data_path = getuploadpath({"college":college,"year":year,"grade":grade,"term":term}) 96 | 97 | print('判断状态:', up_path, data_path) 98 | code = STATUS_NOUPLOAD 99 | if not os.path.exists(up_path): 100 | code = STATUS_NOUPLOAD 101 | if os.path.exists(up_path) and not os.path.exists(data_path): 102 | code = STATUS_NOPARSE 103 | if os.path.exists(data_path): 104 | code = STATUS_DONE 105 | 106 | return code 107 | 108 | def getuploadpath(formdata): 109 | uploadfile ="{}-{}-{}-{}.xls".format(formdata['college'], formdata['year'], formdata['grade'], formdata['term']) 110 | datafile = "{}-{}-{}-{}.csv".format(formdata['college'],formdata['year'], formdata['grade'], formdata['term']) 111 | return os.path.join(UPLOAD_PATH ,uploadfile), os.path.join(UPDATA_PATH, datafile) 112 | 113 | # 处理文件--将处理好的文件保存到uploads的updata/上 114 | @api_blue.route('/data/handle', methods=['POST']) 115 | def handle_file(): 116 | if request.method == 'POST': 117 | formdata = request.json 118 | 119 | up_path,data_path = getuploadpath(formdata) 120 | 121 | try: 122 | 123 | save_csv = data_path.replace('.xls', '.csv') # 保存的路径 124 | print("解析数据的路径:", up_path, save_csv) 125 | 126 | excel = pd.ExcelFile(up_path) 127 | big_data_name = excel.sheet_names # 拿到所有的sheetname 128 | print(big_data_name) 129 | for needs in need_columns: # 循环所有可能出现的表头 130 | # 增加多两列数据 131 | print(needs) 132 | for i in big_data_name: # 循环所有的sheetname 133 | data = pd.read_excel(up_path, sheet_name=i, header=2,converters={u'学号':str}) 134 | 135 | headers = data.columns.tolist() # 将表头转换成列表的形式 136 | 137 | if headers == needs: # 将可能出现的表头与excel里面的header对应 138 | data = data.drop(columns=['排名']) # 删除排名 139 | # data['年级'] = re.findall('\w+级', filenames)[0] 140 | # data['学期'] = re.findall('.*?(第.*?期).*?', filenames)[0] 141 | data['年级'] = formdata['grade'] 142 | if formdata['term']=="term1": 143 | term="第一学期" 144 | elif formdata['term']=="term2": 145 | term="第二学期" 146 | data['学期'] = term 147 | data['年度']= formdata['year'] 148 | data['学院']=formdata['college'] 149 | 150 | head = data.columns.tolist() 151 | app = [] 152 | 153 | 154 | for k in range(0, len(key)): # 替换表头的名字 -- 将中文的表头变成英文的表头,固定死 155 | if head[k] == key[k]: 156 | pass 157 | else: 158 | head[k] = key[k] 159 | for h in head: 160 | app.append(need_word[h]) 161 | data.columns = app 162 | data.to_csv(save_csv, encoding='utf-8', index=False) 163 | 164 | # 需要改数据库和数据表 165 | print("成功保存为csv文件") 166 | time.sleep(3) 167 | try: 168 | data.to_sql("zhsz", con=engine, if_exists='append', index=False) 169 | print("导入数据库成功") 170 | except: 171 | print() 172 | 173 | # 修改上传数据库代码 174 | return api_result(0,msg="导入数据到mysql成功!") 175 | 176 | 177 | except Exception as e: 178 | return api_result(-1,msg="导入数据到mysql失败!"+str(e)) 179 | 180 | else: 181 | return api_result(0,msg="Metho not allow") 182 | 183 | 184 | @api_blue.route('/data/truncate', methods=['POST']) 185 | @login_required 186 | def truncate(): 187 | # 清空表 188 | print("正在清空表...") 189 | 190 | return "ok" 191 | 192 | # uploaded 193 | @api_blue.route("/data/uploaded",methods=['POST']) 194 | @login_required 195 | def uploaded(): 196 | result = get_upload_data() 197 | return api_result(0,data=result) 198 | # 扫描上传的目录,获取上传的文件信息 199 | def get_upload_data(): 200 | files = os.listdir(UPLOAD_PATH) 201 | # file 202 | result = [] 203 | for file in files: 204 | if not file.endswith(".xls"): 205 | continue 206 | name = file.replace(".xls",'') 207 | college,year,grade,term = name.split("-") 208 | result.append({ 209 | 'college':college, 210 | 'year':year, 211 | 'grade':grade, 212 | 'term':term, 213 | 'state':getstate(college, year,grade,term) 214 | }) 215 | return result 216 | 217 | # 判断文件在不在 218 | # @api_blue.route('/data/files', methods=['POST']) 219 | # def files(): 220 | # json = request.json 221 | # year = int(json['year']) 222 | 223 | # files = [] 224 | # for i in range(year - 2, year + 1): 225 | # state = getstate(year, i, "term1") 226 | # files.append({ 227 | # 'year': year, 228 | # 'grade': str(i), 229 | # 'college': "大数据与人工智能学院", 230 | # 'term': "term1", 231 | # 'state': state 232 | # }) 233 | 234 | # state = getstate(year, i, "term2") 235 | # files.append({ 236 | # 'year': year, 237 | # 'grade': str(i), 238 | # 'college': "大数据与人工智能学院", 239 | # 'term': "term2", 240 | # 'state': state 241 | # }) 242 | # return jsonify(files) 243 | term_names={ 244 | 'term1':'第一学期', 245 | 'term2':'第二学期' 246 | } 247 | @api_blue.route('/data/delete', methods=['POST']) 248 | @login_required 249 | def delete_file(): 250 | if request.method == 'POST': 251 | # aa=requests.get('http://127.0.0.1:5000/delete?filename=aa.xls') 252 | uploadfile , datafile= getuploadpath( request.json) 253 | year = request.json['year'] 254 | grade = request.json['grade'] 255 | term = request.json['term'] 256 | 257 | #学院 258 | college=request.json['college'] 259 | 260 | if term in term_names.keys(): 261 | term = term_names[term] 262 | # timestamp = request.args.get('timestamp') 263 | # logger.debug('delete file : %s, timestamp is %s' % (filename, timestamp)) 264 | try: 265 | fullfile = os.path.join(UPLOAD_PATH,uploadfile) 266 | if os.path.exists(fullfile): 267 | os.remove(fullfile) 268 | fullfile = os.path.join(UPDATA_PATH,datafile) 269 | if os.path.exists(fullfile): 270 | os.remove(fullfile) 271 | print("delete from bigdata where college='{college}' year='{year}' and grade='{grade}' and semester='{term}'".format(year=year,term=term,grade=grade,college=college)) 272 | result=Bigtable.query.filter(Bigtable.year==year).delete() 273 | db.session.commit() 274 | return api_result(0,msg="删除数据成功,删除条数:"+str(result)) 275 | # database 276 | except Exception as e: 277 | 278 | return api_result(-1,msg="删除数据失败:"+str(e)) 279 | 280 | else: 281 | return api_result(-1,msg="method not allow") 282 | 283 | -------------------------------------------------------------------------------- /zhsz_api/controllers/logonav.py: -------------------------------------------------------------------------------- 1 | # logo 导航 和学院界面的数据请求 2 | 3 | from flask import Blueprint 4 | # 5 | from zhsz_api.models import Bigtable 6 | from sqlalchemy import * 7 | from flask import request 8 | from . import api_blue 9 | # api_blue = Blueprint('nav',__name__,url_prefix='/nav') 10 | import re 11 | from flask_login import login_required 12 | # query all class 13 | 14 | def getListDict(list_dio,key,value): 15 | for item in list_dio: 16 | if item[key]==value: 17 | return item 18 | return None 19 | 20 | # 查询数据库里所有的班级 21 | @api_blue.route("/nav/classes",methods=['POST']) 22 | @login_required 23 | def get_classes(): 24 | formdata = request.json 25 | print("请求班级数据:",formdata) 26 | # 指定学院的 27 | college = formdata['college'] 28 | 29 | # print(help(distinct)) 30 | result = Bigtable.query.with_entities( distinct( Bigtable.year)).all() 31 | years = [ i[0] for i in result] 32 | print("years:...",years) 33 | if len(years)==0: 34 | return { 35 | 'code':-1, 36 | 'msg':"year data zero!!" 37 | } 38 | if 'year' not in request.form: 39 | year=years[-1] 40 | else: 41 | year = request.js 42 | 43 | result = Bigtable.query.with_entities( distinct( Bigtable.year)).all() 44 | years = [ i[0] for i in result] 45 | print("years:...",years) 46 | 47 | 48 | result=Bigtable.query.with_entities( distinct( Bigtable.gk_class).label("class")).filter(Bigtable.college==college).all() 49 | 50 | classes = [ i[0] for i in result] 51 | # process to .. 52 | 53 | ''' 54 | classes:[{ 55 | label:"17", value:"17", children:[ 56 | {label:"大数据",value:"bigdata"}, 57 | {label:"云计算",value:"clound"} 58 | ] 59 | }, 60 | { 61 | label:"18",value:"18",children:[{label:"大数据",value:"bigdata"}, 62 | {label:"云计算",value:"clound"}] 63 | } 64 | ], 65 | ''' 66 | results=[] 67 | for clazz in classes: 68 | print(clazz) 69 | items =[ i for i in re.split("(\d+)",clazz) if i!=""] 70 | print(items) 71 | if len(items)!=3: 72 | print("error class name:",clazz) 73 | grade=items[0] 74 | classname = items[1] 75 | if len(items)>2: 76 | classnum = items[2] 77 | else: 78 | classnum='0' 79 | 80 | grade_dict = getListDict(results,'value',grade) 81 | if grade_dict is None: 82 | grade_dict={ 83 | "value":grade, 84 | "label":grade, 85 | "children":[] 86 | 87 | } 88 | print(grade_dict) 89 | results.append(grade_dict) 90 | 91 | class_dict = getListDict(grade_dict['children'],'value',classname) 92 | if class_dict is None: 93 | class_dict={ 94 | 'value':classname, 95 | 'label':classname, 96 | 'children':[] 97 | } 98 | 99 | grade_dict['children'].append(class_dict) 100 | 101 | 102 | num_dict = getListDict(class_dict['children'],'value',classnum) 103 | if num_dict is None: 104 | 105 | num_dict={ 106 | 'value':classnum, 107 | 'label':classnum, 108 | 109 | } 110 | class_dict['children'].append(num_dict) 111 | # query all year 112 | 113 | 114 | 115 | return { 116 | "data":{ 117 | # 118 | 'classes':results, 119 | 'years':years 120 | } 121 | } 122 | 123 | term_names={ 124 | 'term1':'第一学期', 125 | 'term2':'第二学期', 126 | # 'year':'年度' 127 | } 128 | @api_blue.route("/collage",methods=['POST']) 129 | def collage(): 130 | params = request.json 131 | year=params['year'] 132 | term=params['term'] 133 | college = params['college'] 134 | if term in term_names.keys(): 135 | term = term_names[term] 136 | print("request,arg",params) 137 | 138 | # filter term,year , college 139 | # (Bigtable.semester==params['term'] 140 | if term=="year": 141 | filter_query = Bigtable.query.filter(Bigtable.year==year ,Bigtable.college==college) 142 | else: 143 | filter_query = Bigtable.query.filter( and_( Bigtable.year==year,Bigtable.semester==term ),Bigtable.college==college) 144 | 145 | # Bigtable.query. 146 | 147 | # gpa_score 148 | result = {} 149 | temp = Bigtable.query.filter(Bigtable.college==college).with_entities(Bigtable.GPA,Bigtable.political_edu+Bigtable.physical_heal+Bigtable.innovation_entrep+Bigtable.technical_skills+Bigtable.volunte+Bigtable.human_art+Bigtable.zh_theory).all() 150 | print("len:",len(temp)) 151 | gpas = [] 152 | scores = [] 153 | 154 | for i in temp: 155 | gpas.append(i[0]) 156 | scores.append(i[1]) 157 | gpa_score = { 158 | 'gpas':gpas, 159 | 'scores':scores 160 | } 161 | 162 | # ------------------------------range --------------------- 163 | myrange = [10,20,30,40,50,60,70,80] 164 | 165 | range_text = [ "[{},{})".format(myrange[i],myrange[i+1]) for i in range(0,len(myrange)-1)] 166 | # less than 0 167 | range_text.insert(0,"[0,10)]") 168 | range_text.append("80+") 169 | print(range_text) 170 | ranges=[] 171 | print(func) 172 | term1_data = Bigtable.query.filter(Bigtable.college==college, Bigtable.semester=="第一学期").with_entities( func.interval( Bigtable.zh_score, *myrange).label("range"),func.count(1)).group_by('range').all() 173 | term1 = [0]*len(range_text) 174 | for item in term1_data: 175 | term1[item[0]] = item[1] 176 | 177 | # range 178 | term2_data = Bigtable.query.filter(Bigtable.college==college,Bigtable.semester=="第二学期").with_entities( func.interval( Bigtable.zh_score, *myrange).label("range"),func.count(1)).group_by('range').all() 179 | term2 = [0]*len(range_text) 180 | for item in term2_data: 181 | term2[item[0]] = item[1] 182 | 183 | 184 | # print(term1) 185 | 186 | # print(term1_data) 187 | # indexes 188 | # all zhibiao 189 | indexnames= { 190 | 'political_edu':"思想政治", 191 | 'physical_heal':"身心健康", 192 | 'innovation_entrep':"创新创业", 193 | 'technical_skills':'技术技能', 194 | 'volunte':'志愿服务', 195 | 'human_art':'人文艺术', 196 | 'zh_theory':'综合素质理论', 197 | 'zh_score':"平均分" 198 | 199 | } 200 | 201 | # print([i for i in dir(Bigtable) if not i.startswith("_")]) 202 | # get functio nhelp 203 | 204 | 205 | querycols = [] 206 | for key,name in indexnames.items(): 207 | querycols.append( func.round(func.avg( getattr( Bigtable, key) ),2)) 208 | scores = filter_query.with_entities(*querycols).first() 209 | indexes = { 210 | 'indexes':list(indexnames.values()), 211 | 'scores':list(scores) 212 | 213 | } 214 | #---------------------------tops--------------------- 215 | 216 | top={} 217 | # top 5 class 218 | temp = Bigtable.query.with_entities(Bigtable.gk_class,func.avg(Bigtable.human_art).label("score")).group_by(Bigtable.gk_class).order_by(desc(column("score"))).limit(5).all() 219 | # [('18云计算1', 5.73404255319149), ('18oracle', 5.531914893617022), ('17移动互联1', 5.027777777777778), ('18大数据2', 4.758196721311475), ('18云计算2', 4.458333333333333)] 220 | #top 50 student 221 | #zhijie na 222 | temp = Bigtable.query.with_entities(Bigtable.style_id,Bigtable.stu_name, func.round(func.avg(Bigtable.human_art),2).label("score")).group_by(Bigtable.style_id,Bigtable.stu_name).order_by(desc(column("score"))).limit(50).all() 223 | # print(temp) 224 | 225 | 226 | for key , name in indexnames.items(): 227 | # column 228 | col = getattr(Bigtable,key) 229 | temp = filter_query.with_entities(Bigtable.gk_class,func.round(func.avg(col),1).label("score")).group_by(Bigtable.gk_class).order_by(desc(column("score"))).limit(5).all() 230 | classes = [] 231 | students = [] 232 | for i in temp: 233 | classes.append({ 234 | 'name':i[0], 235 | 'score':i[1] 236 | }) 237 | temp = filter_query.with_entities(Bigtable.style_id,Bigtable.stu_name,func.round(func.avg(col),1).label("score")).group_by(Bigtable.style_id,Bigtable.stu_name).order_by(desc(column("score"))).limit(50).all() 238 | for i in temp: 239 | students.append({ 240 | 'name':i[1], 241 | 'id':i[0], 242 | 'score':i[2] 243 | 244 | }) 245 | top[name]={ 246 | 'classes':classes, 247 | 'students':students 248 | } 249 | 250 | #---------------------card data------------- 251 | year_score=Bigtable.query.filter(Bigtable.year==year,Bigtable.college==college).with_entities(func.round(func.avg(Bigtable.zh_score),2)).scalar() 252 | term1_score = Bigtable.query.filter(Bigtable.college==college, and_( Bigtable.year==year,Bigtable.semester==term_names['term1'])).with_entities(func.round(func.avg(Bigtable.zh_score),2)).scalar() 253 | term2_score = Bigtable.query.filter(Bigtable.college==college, and_( Bigtable.year==year,Bigtable.semester==term_names['term2'])).with_entities(func.round(func.avg(Bigtable.zh_score),2)).scalar() 254 | 255 | # select year,semester,avg(zh_score ) from bigdata group by year,semester; 256 | #-------------------------trend------------------- 257 | 258 | result = Bigtable.query.with_entities(Bigtable.year,Bigtable.semester,func.avg(Bigtable.zh_score)).group_by(Bigtable.year,Bigtable.semester).all() 259 | print(result) 260 | 261 | years=[] 262 | term1_trend=[] 263 | term2_trend=[] 264 | # [('2018', '第一学期', 41.39818472268591), ('2018', '第二学期', 44.13349394817429)] 265 | # m 266 | for i in range(0,len(result),2): 267 | years.append(result[i][0]) 268 | term1_trend.append(result[i][2]) 269 | if i+10: 82 | term2_paiming = temp[0] 83 | 84 | classCard = { 85 | "term1_score": term1_score, # 第一学期的综合素平均分 86 | "term2_score": term2_score, # 第二学期的综合素平均分 87 | "term1_paiming": term1_paiming, # 第一学期在全院的排名 88 | "term2_paiming": term2_paiming # 第二学期在全院的排名 89 | # https://blog.csdn.net/shiwodecuo/article/details/54632839 90 | # https://blog.csdn.net/qq1032350287/article/details/86693068 91 | } 92 | 93 | 94 | # 3--- 95 | # 整个年度,不管学期 96 | grade = "20" + class_name[:2] 97 | 98 | college_value = 'select avg(political_edu),avg(physical_heal),avg(innovation_entrep),avg(technical_skills),avg(volunte),avg(human_art),avg(zh_theory) from zhsz WHERE college="{}" and grade="{}" {};'.format(college,grade, filter_str) 99 | class_value = 'select avg(political_edu),avg(physical_heal),avg(innovation_entrep),avg(technical_skills),avg(volunte),avg(human_art),avg(zh_theory) from zhsz WHERE college="{}" and gk_class="{}" {};'.format(college,class_name, filter_str) 100 | 101 | print(college_value) 102 | db.execute(college_value) 103 | CollegeValue = db.fetchall()[0] 104 | 105 | db.execute(class_value) 106 | ClassValue = db.fetchall()[0] 107 | 108 | suchindexscores = [ 109 | { 110 | 'value':CollegeValue,'name':'学院指标平均分' 111 | }, 112 | { 113 | 'value':ClassValue,'name':'班级指标平均分' 114 | }] 115 | 116 | # 4---改成distinct 117 | student_name = ' select distinct stu_name from zhsz where college="{}" and gk_class="{}" and year="{}" ;'.format(college,class_name, year) 118 | stu_name_app = [] 119 | db.execute(student_name) 120 | StudentName = db.fetchall() 121 | for stuName in StudentName: 122 | stu_name_app.append(stuName[0]) 123 | students = { 124 | "student": stu_name_app 125 | } 126 | 127 | # 5--- 128 | indexs = {'political_edu': '思想政治', 'physical_heal': "身心健康", 'innovation_entrep': '创新创业', 129 | 'technical_skills': '技术技能', 'volunte': '志愿服务', 'human_art': '人文艺术', 'zh_theory': '综合素质理论','zh_score':"总分Top5"} 130 | 131 | 132 | 133 | topstudent = {} 134 | for key, value in indexs.items(): 135 | name_app = [] 136 | score_app = [] 137 | all_sql = 'select stu_name,{} from zhsz where college="{}" and gk_class="{}" {filter_str} order by {} desc limit 5;'.format(key, college,class_name, key,filter_str=filter_str) 138 | db.execute(all_sql) 139 | allName = db.fetchall() 140 | print('all',all_sql) 141 | 142 | for name, score in allName: 143 | name_app.append(name) 144 | score_app.append(score) 145 | 146 | topstudent[value] = { 147 | 'names': name_app, 148 | 'scores': score_app 149 | } 150 | 151 | # 6- 152 | total_sql = 'select count(stu_name),CASE ' \ 153 | 'when score >= 0 and score <= 10 THEN "0-10" ' \ 154 | 'when score > 10 and score <= 20 THEN "11-20" ' \ 155 | 'when score > 20 and score <= 30 THEN "21-30" ' \ 156 | 'when score > 30 and score <= 40 THEN "31-40" ' \ 157 | 'when score > 40 and score <=50 THEN "41-50" ' \ 158 | 'when score>50 THEN "50以上" end as "总分区间" from zhsz ' \ 159 | 'where college="{}" and gk_class="{}" {filter_str} ' \ 160 | 'group by CASE when score >= 0 and score <= 10 THEN "0-10" ' \ 161 | 'when score > 10 and score <= 20 THEN "11-20" ' \ 162 | 'when score > 20 and score <= 30 THEN "21-30" ' \ 163 | 'when score > 30 and score <= 40 THEN "31-40" ' \ 164 | 'when score > 40 and score <=50 THEN "41-50" ' \ 165 | 'when score>50 THEN "50以上" end ' \ 166 | 'order by CASE when score >= 0 and score <= 10 THEN "0-10" ' \ 167 | 'when score > 10 and score <= 20 THEN "11-20" ' \ 168 | 'when score > 20 and score <= 30 THEN "21-30" ' \ 169 | 'when score > 30 and score <= 40 THEN "31-40" ' \ 170 | 'when score > 40 and score <=50 THEN "41-50" ' \ 171 | 'when score>50 THEN "50以上" end;'.format(college,class_name, filter_str=filter_str) 172 | 173 | db.execute(total_sql) 174 | TotalScores = db.fetchall() 175 | allscores = [] 176 | total_app = [] 177 | for people, total in TotalScores: 178 | total_score = {} 179 | total_score['value'] = people 180 | total_score['name'] = total 181 | allscores.append(total_score) 182 | total_app.append(total) 183 | 184 | totalscores = { 185 | "ranges": total_app, 186 | "allscores": allscores 187 | } 188 | 189 | return jsonify( 190 | {"classjbCard": classjbCard, "classCard": classCard, "suchindexscores": suchindexscores, "students": students, 191 | "topstudent": topstudent, "totalscores": totalscores}) 192 | 193 | 194 | 195 | 196 | @api_blue.route('/geren', methods=['POST']) 197 | # @login_required 198 | def geren(): 199 | if request.method == 'POST': 200 | 201 | formdata = request.json 202 | 203 | year = formdata.get('year') 204 | stu_name = formdata.get('stu_id') 205 | class_name = formdata.get('classid') 206 | college=formdata.get('college') 207 | if formdata['term']=="term1": 208 | semester="第一学期" 209 | elif formdata['term']=="term2": 210 | semester="第二学期" 211 | 212 | if formdata['term']=='year': 213 | # 年度的什么都不过滤 214 | filter_sql = 'year="{}"'.format(year) 215 | else: 216 | # 学期的就过滤学期 217 | 218 | filter_sql = 'year="{}" and semester="{}"'.format(year,semester) 219 | 220 | # 特殊处理 221 | 222 | 223 | 224 | # 1-- 225 | stu_score = 'select zh_score from zhsz where stu_name="{}" and semester="第一学期" and year="{}" and college="{}";'.format( 226 | stu_name, year,college) 227 | db.execute(stu_score) 228 | 229 | term1_avlscore = db.fetchall()[0][0] 230 | 231 | stu_yuan_rank = 'select (select count(distinct zh) from (select zh_score as zh from zhsz where semester="第一学期" and year="{}") as a where zh>=s.zh) as "rank" from (select stu_name,zh_score as zh from zhsz where semester="第一学期" and year="{}" and college="{}") as s where stu_name="{}" order by s.zh desc;'.format(year, year,college, stu_name) 232 | db.execute(stu_yuan_rank) 233 | print("stu_yuan_rank",stu_yuan_rank) 234 | term1_yranking = db.fetchone()[0] 235 | stu_class_rank = 'select (select count(distinct zh) from (select zh_score as zh from zhsz where gk_class="{}" and semester="第一学期" and year="{}") as a where zh>=s.zh) as "rank" from (select stu_name,zh_score as zh from zhsz where gk_class="{}" and semester="第一学期" and year="{}" and college="{}") as s where stu_name="{}" order by s.zh desc;'.format(class_name, year, class_name, year, college,stu_name) 236 | db.execute(stu_class_rank) 237 | term1_cranking = db.fetchone()[0] 238 | studentCard1 = { 239 | "term1_avlscore": term1_avlscore, ##第一学期综合素质平均分 240 | "term1_yranking": term1_yranking, ##第一学期综合素质在全院排名 241 | "term1_cranking": term1_cranking ##第一学期综合素质在全班排名 242 | } 243 | 244 | # 1_1-- 245 | stu_score_2 = 'select zh_score from zhsz where stu_name="{}" and semester="第二学期" and year="{}" and college="{}";'.format( 246 | stu_name, year,college) 247 | db.execute(stu_score_2) 248 | 249 | term2_avlscore = "无此学期数据" 250 | temp = db.fetchall() 251 | if len(temp)>0: 252 | term2_avlscore=temp[0][0] 253 | stu_yuan_rank_2 = 'select (select count(distinct zh) from (select zh_score as zh from zhsz where semester="第二学期" and year="{}") as a where zh>=s.zh) as "rank" from (select stu_name,zh_score as zh from zhsz where semester="第二学期" and year="{}" and college="{}") as s where stu_name="{}" order by s.zh desc;'.format( 254 | year, year, college,stu_name) 255 | 256 | db.execute(stu_yuan_rank_2) 257 | term2_yranking = "无此学期数据" 258 | temp = db.fetchone() 259 | if not temp ==None: 260 | term2_yranking=temp[0] 261 | 262 | stu_class_rank_2 = 'select (select count(distinct zh) from (select zh_score as zh from zhsz where gk_class="{}" and semester="第二学期" and year="{}") as a where zh>=s.zh) as "rank" from (select stu_name,zh_score as zh from zhsz where gk_class="{}" and semester="第二学期" and year="{}" and college="{}") as s where stu_name="{}" order by s.zh desc;'.format( 263 | class_name, year, class_name, year, college,stu_name) 264 | db.execute(stu_class_rank_2) 265 | temp = db.fetchone() 266 | term2_cranking = "无此学期数据" if temp == None else temp[0] 267 | studentCard2 = { 268 | "term2_avlscore": term2_avlscore, ##第二学期综合素质平均分 269 | "term2_yranking": term2_yranking, ##第二学期综合素质在全院排名 270 | "term2_cranking": term2_cranking ##第二学期综合素质在全班排名 271 | } 272 | 273 | # 2-- 274 | stu_zhibiao_score = db2.session.execute( 275 | 'select political_edu,physical_heal,innovation_entrep,technical_skills,volunte,human_art,zh_theory from zhsz where stu_name="{}" and {filter_sql} and college="{}";'.format( 276 | stu_name ,college,filter_sql=filter_sql)).fetchone() 277 | print("学生指标sql:",'select political_edu,physical_heal,innovation_entrep,technical_skills,volunte,human_art,zh_theory from zhsz where stu_name="{}" and {filter_sql} and college="{}";'.format( 278 | stu_name, college,filter_sql=filter_sql)) 279 | class_zhibiao_avg_score = db2.session.execute( 280 | 'select avg(political_edu),avg(physical_heal),avg(innovation_entrep),avg(technical_skills),avg(volunte),avg(human_art),avg(zh_theory) from zhsz where gk_class="{}" and {filter_sql} and college="{}";'.format( 281 | class_name,college,filter_sql=filter_sql)) 282 | yuan_zhibiao_avg_score = db2.session.execute( 283 | 'select avg(political_edu),avg(physical_heal),avg(innovation_entrep),avg(technical_skills),avg(volunte),avg(human_art),avg(zh_theory) from zhsz where college="{}" and {filter_sql};'.format( 284 | college,filter_sql=filter_sql)) 285 | suchscores = [] 286 | suchscores2 = [] 287 | suchscores3 = [] 288 | name1 = '学院指标平均分' 289 | name2 = '班级指标平均分' 290 | name3 = '学生指标分数' 291 | if stu_zhibiao_score is not None: 292 | for i in stu_zhibiao_score: 293 | suchscores.append(i) 294 | for i_1 in class_zhibiao_avg_score: 295 | suchscores2.append(i_1) 296 | for i_2 in yuan_zhibiao_avg_score: 297 | suchscores3.append(i_2) 298 | 299 | suchindex = [{ 300 | 'value': list(suchscores3[0].itervalues()), 301 | 'name': name1 302 | }, { 303 | 'value': list(suchscores2[0].itervalues()), 304 | 'name': name2 305 | }, { 306 | 'value': suchscores, 307 | 'name': name3 308 | } 309 | ] 310 | ##各指标雷达 311 | 312 | # 3-- 313 | indexs = {'political_edu': '思想政治', 'physical_heal': "身心健康", 'innovation_entrep': '创新创业', 314 | 'technical_skills': '技术技能', 'volunte': '志愿服务', 'human_art': '人文艺术', 'zh_theory': '综合素质理论'} 315 | yuanData = [] 316 | ClassData = [] 317 | for key, value in indexs.items(): 318 | score = db2.session.execute( 319 | 'select {} from zhsz where stu_name="{}" and {filter_sql} and college="{}";'.format(key, 320 | stu_name, 321 | college ,filter_sql=filter_sql ) ).fetchone() 322 | rank = db2.session.execute( 323 | 'select (select count(distinct zh) from (select {} as zh from zhsz where {filter_sql}) as a where zh>=s.zh) as "rank" from (select stu_name,{} as zh from zhsz where {filter_sql} and college="{}") as s where stu_name="{}" order by s.zh desc;'.format( 324 | key, key, college,stu_name,filter_sql=filter_sql )).fetchone() 325 | 326 | if score is not None: 327 | yuanData.append({ 328 | 'Collegindex': value, 329 | 'Collegscores': score[0], 330 | 'Collegranking': rank[0] 331 | }) 332 | print("yuanData",yuanData) 333 | 334 | 335 | for key1, value1 in indexs.items(): 336 | sql_score1='select {} from zhsz where stu_name="{}" and {filter_sql} and gk_class="{}" and college="{}";'.format(key1, stu_name,class_name,college,filter_sql=filter_sql) 337 | print("sql_score1",sql_score1) 338 | score1 = db2.session.execute(sql_score1).fetchone() 339 | print('score1',score1) 340 | rank1 = db2.session.execute( 341 | 'select (select count(distinct zh) from (select {} as zh from zhsz where gk_class="{}" and {filter_sql}) as a where zh>=s.zh) as "rank" from (select stu_name,{} as zh from zhsz where gk_class="{}" and {filter_sql} and college="{}") as s where stu_name="{}" order by s.zh desc;'.format( 342 | key1, class_name, key1, class_name, college,stu_name,filter_sql=filter_sql)).fetchone() 343 | if score1 is not None: 344 | ClassData.append({ 345 | 'Classindex': value1, 346 | 'Classscores': score1[0], 347 | 'Classranking': rank1[0] 348 | }) 349 | data1 = { 350 | 'CollegeData': yuanData # 各指标在全院排名和各指标分数 351 | } 352 | data2 = { 353 | 'ClassData': ClassData # 各指标在全班排名和各指标分数 354 | } 355 | 356 | return jsonify( 357 | {"studentCard1": studentCard1, "studentCard2": studentCard2, "suchindexscores": suchindex, "data1": data1, 358 | "data2": data2}) 359 | 360 | 361 | 362 | -------------------------------------------------------------------------------- /zhsz_api/extensions.py: -------------------------------------------------------------------------------- 1 | from flask_cors import CORS 2 | from flask_login import LoginManager 3 | from flask_wtf import CSRFProtect 4 | from flask_bcrypt import Bcrypt 5 | from flask_openid import OpenID 6 | 7 | csrfp=CSRFProtect() 8 | cors=CORS() 9 | lm=LoginManager() 10 | bcrypt=Bcrypt() 11 | oid=OpenID() -------------------------------------------------------------------------------- /zhsz_api/forms.py: -------------------------------------------------------------------------------- 1 | from wtforms import Form 2 | from wtforms import StringField, PasswordField, BooleanField 3 | from wtforms.validators import ValidationError, Length 4 | from zhsz_api.models import User 5 | 6 | 7 | class LoginForm(Form): 8 | username = StringField('Username', validators=[Length(max=64)]) 9 | password = PasswordField('Password',validators=[Length(min=8,max=16)]) 10 | remember = BooleanField('Remember Me') 11 | 12 | def validate_username(self, field): 13 | if not self.get_user(): 14 | raise ValidationError('Invalid username!') 15 | 16 | def validate_password(self, field): 17 | if not self.get_user(): 18 | return 19 | if not self.get_user().check_password(field.data): 20 | raise ValidationError('Incorrect password!') 21 | 22 | def get_user(self): 23 | return User.query.filter_by(username=self.username.data).first() 24 | 25 | 26 | class RegisterForm(Form): 27 | username = StringField('Username', validators=[Length(max=64)]) 28 | password = PasswordField('Password',validators=[Length(min=8,max=16)]) 29 | confirm = PasswordField('Confirm Password') 30 | 31 | def validate_username(self, field): 32 | if User.query.filter_by(username=field.data).count() > 0: 33 | raise ValidationError('Username %s already exists!' % field.data) 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /zhsz_api/models.py: -------------------------------------------------------------------------------- 1 | from zhsz_api.extensions import bcrypt 2 | from flask_sqlalchemy import SQLAlchemy 3 | from flask_login import UserMixin 4 | 5 | db=SQLAlchemy() 6 | 7 | class User(db.Model, UserMixin): 8 | ''' 9 | 用户模型 10 | ''' 11 | __tablename__ = 'User' 12 | id = db.Column(db.Integer, primary_key=True,autoincrement=True) 13 | username = db.Column(db.String(64), unique=True) 14 | password = db.Column(db.String(200)) 15 | 16 | def __init__(self, **kwargs): 17 | password = kwargs.pop('password') 18 | password = bcrypt.generate_password_hash(password) 19 | kwargs['password'] = password 20 | super(User, self).__init__(**kwargs) 21 | 22 | def check_password(self, password): 23 | return bcrypt.check_password_hash(self.password, password) 24 | 25 | def to_json(self): 26 | return {'id': self.id, 'username': self.username} 27 | 28 | ''' 29 | #计算机工程技术学院 30 | class College_of_computer_engineering_technology(db.Model,UserMixin): 31 | __tablename__ = 'computer_engineering' 32 | primary_id = db.Column(db.Integer, primary_key=True, autoincrement=True) 33 | style_id = db.Column(db.String(50), nullable=True) # 不能以学号为主键,因为在17级第一学期和第二学期的时候,同一个人会发生主键冲突 34 | stu_name = db.Column(db.String(100)) 35 | political_edu = db.Column(db.Float) 36 | physical_heal = db.Column(db.Float) 37 | innovation_entrep = db.Column(db.Float) 38 | technical_skills = db.Column(db.Float) 39 | volunte = db.Column(db.Float) 40 | human_art = db.Column(db.Float) 41 | zh_theory = db.Column(db.Float) 42 | score = db.Column(db.Float) 43 | GPA = db.Column(db.Float) 44 | zh_score = db.Column(db.Float) 45 | gk_class = db.Column(db.String(100)) 46 | grade = db.Column(db.String(50)) # 年度 比如这个表是2018年度的 47 | semester = db.Column(db.String(50)) # 学期 48 | year = db.Column(db.String(50)) # 年级比如 17大数据1班,那么就是2017级 49 | ''' 50 | 51 | #大数据与人工智能 52 | class Bigtable(db.Model,UserMixin): 53 | #__tablename__='bigdata_ai' 54 | __tablename__ = 'zhsz' 55 | primary_id=db.Column(db.Integer,primary_key=True,autoincrement=True) 56 | style_id=db.Column(db.String(50),nullable=True) #不能以学号为主键,因为在17级第一学期和第二学期的时候,同一个人会发生主键冲突 57 | stu_name=db.Column(db.String(100)) 58 | political_edu=db.Column(db.Float) 59 | physical_heal=db.Column(db.Float) 60 | innovation_entrep=db.Column(db.Float) 61 | technical_skills=db.Column(db.Float) 62 | volunte=db.Column(db.Float) 63 | human_art=db.Column(db.Float) 64 | zh_theory=db.Column(db.Float) 65 | score=db.Column(db.Float) 66 | GPA=db.Column(db.Float) 67 | zh_score=db.Column(db.Float) 68 | gk_class=db.Column(db.String(100)) 69 | grade=db.Column(db.String(50)) #年度 比如这个表是2018年度的 70 | semester=db.Column(db.String(50)) #学期 71 | year = db.Column(db.String(50)) #年级比如 17大数据1班,那么就是2017级 72 | college=db.Column(db.String(50)) --------------------------------------------------------------------------------