├── .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))
--------------------------------------------------------------------------------