From 1e302df9edd8039f2b9e26821ed626f2f50b90bf Mon Sep 17 00:00:00 2001 From: Lys <17608410+lys1359664647@user.noreply.gitee.com> Date: Mon, 21 Sep 2026 22:13:04 +0800 Subject: [PATCH] aaa --- student_system_final/.idea/.gitignore | 10 ++ .../inspectionProfiles/Project_Default.xml | 10 ++ .../inspectionProfiles/profiles_settings.xml | 6 + student_system_final/.idea/misc.xml | 7 + student_system_final/.idea/modules.xml | 8 + student_system_final/.idea/student_system.iml | 12 ++ .../__pycache__/database.cpython-310.pyc | Bin 0 -> 772 bytes .../__pycache__/main.cpython-310.pyc | Bin 0 -> 1482 bytes student_system_final/aaa.py | 39 ++++ student_system_final/api1/__init__.py | 0 .../api1/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 166 bytes .../api1/__pycache__/classes.cpython-310.pyc | Bin 0 -> 1733 bytes .../api1/__pycache__/scores.cpython-310.pyc | Bin 0 -> 1164 bytes .../__pycache__/statistic.cpython-310.pyc | Bin 0 -> 2349 bytes .../api1/__pycache__/students.cpython-310.pyc | Bin 0 -> 2198 bytes .../api1/__pycache__/teacher.cpython-310.pyc | Bin 0 -> 1814 bytes .../api1/__pycache__/work.cpython-310.pyc | Bin 0 -> 1332 bytes student_system_final/api1/classes.py | 60 +++++++ student_system_final/api1/scores.py | 35 ++++ student_system_final/api1/statistic.py | 80 +++++++++ student_system_final/api1/students.py | 48 +++++ student_system_final/api1/teacher.py | 46 +++++ student_system_final/api1/work.py | 31 ++++ student_system_final/dao/__init__.py | 0 .../dao/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 165 bytes .../dao/__pycache__/class_dao.cpython-310.pyc | Bin 0 -> 2786 bytes .../dao/__pycache__/score_dao.cpython-310.pyc | Bin 0 -> 2206 bytes .../__pycache__/statistic_dao.cpython-310.pyc | Bin 0 -> 4677 bytes .../__pycache__/student_dao.cpython-310.pyc | Bin 0 -> 2183 bytes .../__pycache__/teacher_dao.cpython-310.pyc | Bin 0 -> 2092 bytes .../dao/__pycache__/work_dao.cpython-310.pyc | Bin 0 -> 2465 bytes student_system_final/dao/class_dao.py | 85 +++++++++ student_system_final/dao/score_dao.py | 59 +++++++ student_system_final/dao/statistic_dao.py | 166 ++++++++++++++++++ student_system_final/dao/student_dao.py | 65 +++++++ student_system_final/dao/teacher_dao.py | 59 +++++++ student_system_final/dao/work_dao.py | 80 +++++++++ student_system_final/database.py | 34 ++++ student_system_final/main.py | 43 +++++ student_system_final/model/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 167 bytes .../model/__pycache__/classes.cpython-310.pyc | Bin 0 -> 946 bytes .../model/__pycache__/student.cpython-310.pyc | Bin 0 -> 1123 bytes .../__pycache__/student_score.cpython-310.pyc | Bin 0 -> 884 bytes .../model/__pycache__/teacher.cpython-310.pyc | Bin 0 -> 1224 bytes .../model/__pycache__/work.cpython-310.pyc | Bin 0 -> 1110 bytes student_system_final/model/classes.py | 15 ++ student_system_final/model/student.py | 23 +++ student_system_final/model/student_score.py | 18 ++ student_system_final/model/teacher.py | 17 ++ student_system_final/model/work.py | 17 ++ student_system_final/scheme/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 168 bytes .../__pycache__/classes.cpython-310.pyc | Bin 0 -> 1695 bytes .../scheme/__pycache__/scores.cpython-310.pyc | Bin 0 -> 1220 bytes .../__pycache__/students.cpython-310.pyc | Bin 0 -> 2143 bytes .../__pycache__/teachers.cpython-310.pyc | Bin 0 -> 1767 bytes .../scheme/__pycache__/works.cpython-310.pyc | Bin 0 -> 2501 bytes student_system_final/scheme/classes.py | 27 +++ student_system_final/scheme/scores.py | 24 +++ student_system_final/scheme/students.py | 59 +++++++ student_system_final/scheme/teachers.py | 37 ++++ student_system_final/scheme/works.py | 48 +++++ 63 files changed, 1268 insertions(+) create mode 100644 student_system_final/.idea/.gitignore create mode 100644 student_system_final/.idea/inspectionProfiles/Project_Default.xml create mode 100644 student_system_final/.idea/inspectionProfiles/profiles_settings.xml create mode 100644 student_system_final/.idea/misc.xml create mode 100644 student_system_final/.idea/modules.xml create mode 100644 student_system_final/.idea/student_system.iml create mode 100644 student_system_final/__pycache__/database.cpython-310.pyc create mode 100644 student_system_final/__pycache__/main.cpython-310.pyc create mode 100644 student_system_final/aaa.py create mode 100644 student_system_final/api1/__init__.py create mode 100644 student_system_final/api1/__pycache__/__init__.cpython-310.pyc create mode 100644 student_system_final/api1/__pycache__/classes.cpython-310.pyc create mode 100644 student_system_final/api1/__pycache__/scores.cpython-310.pyc create mode 100644 student_system_final/api1/__pycache__/statistic.cpython-310.pyc create mode 100644 student_system_final/api1/__pycache__/students.cpython-310.pyc create mode 100644 student_system_final/api1/__pycache__/teacher.cpython-310.pyc create mode 100644 student_system_final/api1/__pycache__/work.cpython-310.pyc create mode 100644 student_system_final/api1/classes.py create mode 100644 student_system_final/api1/scores.py create mode 100644 student_system_final/api1/statistic.py create mode 100644 student_system_final/api1/students.py create mode 100644 student_system_final/api1/teacher.py create mode 100644 student_system_final/api1/work.py create mode 100644 student_system_final/dao/__init__.py create mode 100644 student_system_final/dao/__pycache__/__init__.cpython-310.pyc create mode 100644 student_system_final/dao/__pycache__/class_dao.cpython-310.pyc create mode 100644 student_system_final/dao/__pycache__/score_dao.cpython-310.pyc create mode 100644 student_system_final/dao/__pycache__/statistic_dao.cpython-310.pyc create mode 100644 student_system_final/dao/__pycache__/student_dao.cpython-310.pyc create mode 100644 student_system_final/dao/__pycache__/teacher_dao.cpython-310.pyc create mode 100644 student_system_final/dao/__pycache__/work_dao.cpython-310.pyc create mode 100644 student_system_final/dao/class_dao.py create mode 100644 student_system_final/dao/score_dao.py create mode 100644 student_system_final/dao/statistic_dao.py create mode 100644 student_system_final/dao/student_dao.py create mode 100644 student_system_final/dao/teacher_dao.py create mode 100644 student_system_final/dao/work_dao.py create mode 100644 student_system_final/database.py create mode 100644 student_system_final/main.py create mode 100644 student_system_final/model/__init__.py create mode 100644 student_system_final/model/__pycache__/__init__.cpython-310.pyc create mode 100644 student_system_final/model/__pycache__/classes.cpython-310.pyc create mode 100644 student_system_final/model/__pycache__/student.cpython-310.pyc create mode 100644 student_system_final/model/__pycache__/student_score.cpython-310.pyc create mode 100644 student_system_final/model/__pycache__/teacher.cpython-310.pyc create mode 100644 student_system_final/model/__pycache__/work.cpython-310.pyc create mode 100644 student_system_final/model/classes.py create mode 100644 student_system_final/model/student.py create mode 100644 student_system_final/model/student_score.py create mode 100644 student_system_final/model/teacher.py create mode 100644 student_system_final/model/work.py create mode 100644 student_system_final/scheme/__init__.py create mode 100644 student_system_final/scheme/__pycache__/__init__.cpython-310.pyc create mode 100644 student_system_final/scheme/__pycache__/classes.cpython-310.pyc create mode 100644 student_system_final/scheme/__pycache__/scores.cpython-310.pyc create mode 100644 student_system_final/scheme/__pycache__/students.cpython-310.pyc create mode 100644 student_system_final/scheme/__pycache__/teachers.cpython-310.pyc create mode 100644 student_system_final/scheme/__pycache__/works.cpython-310.pyc create mode 100644 student_system_final/scheme/classes.py create mode 100644 student_system_final/scheme/scores.py create mode 100644 student_system_final/scheme/students.py create mode 100644 student_system_final/scheme/teachers.py create mode 100644 student_system_final/scheme/works.py diff --git a/student_system_final/.idea/.gitignore b/student_system_final/.idea/.gitignore new file mode 100644 index 0000000..b6b1ecf --- /dev/null +++ b/student_system_final/.idea/.gitignore @@ -0,0 +1,10 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 已忽略包含查询文件的默认文件夹 +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ diff --git a/student_system_final/.idea/inspectionProfiles/Project_Default.xml b/student_system_final/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..146ab09 --- /dev/null +++ b/student_system_final/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/student_system_final/.idea/inspectionProfiles/profiles_settings.xml b/student_system_final/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/student_system_final/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/student_system_final/.idea/misc.xml b/student_system_final/.idea/misc.xml new file mode 100644 index 0000000..1e700dc --- /dev/null +++ b/student_system_final/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/student_system_final/.idea/modules.xml b/student_system_final/.idea/modules.xml new file mode 100644 index 0000000..ecfe1dc --- /dev/null +++ b/student_system_final/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/student_system_final/.idea/student_system.iml b/student_system_final/.idea/student_system.iml new file mode 100644 index 0000000..95a328c --- /dev/null +++ b/student_system_final/.idea/student_system.iml @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/student_system_final/__pycache__/database.cpython-310.pyc b/student_system_final/__pycache__/database.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..afabe87b65354be37b0bdc04214f77600e89a74b GIT binary patch literal 772 zcmY*X%}*0S6rY*>psX$7U@+b|+L-XEL>pr$Lc*bvX#I$rCYx<%gzA3OokdfE2^LTe zR!G1YQGy&WYJ@^K&`^l~$6o1n%gK{h<4lQ&FPXRR_jcZI=KbE-k%$7AwY982Do6kv za&X#22Kw2e!^~lTp#e;&LdaueAX88UQ&dHU1yv%DNLa*D5vei}h>YbTRGWx64b%{B z!l483sXXA*0xOjF>$nlhDNg!gaI*~wQz=C=C45(gxKOqdV#qYzy;IbIhar;!94)MeJ}|=!8I0Pm^_J} zfhZa;vh7Mcvs!7s_I<5h+O2ID{J9T)Wv^PEs+Pai-fq>3oBrNnb$_{DTKT#E`gl)J zS*)$B`U`LT*`1?z8;4Vc22K6PdsgJXI$(9IqI&SLTHb3PBspSX+8!*=`11u$x%0)J zUH9j<>bs?2X}elJAsFF`CXW?OaB(~-W7w2;j&S-baL%wB|B5p=7)y0s>FLhp-7(ur z`5T{urPW|_Em(LN>{NovYU+P6wTD?tH&R%4bv~AkT;7vMiL2rCc}7OL)M!eU5DdXK zNphNImdh%(byMJ#pf~mw3B7c4~D-JN~`*`|aq>o8Q_m z7IO-Y!dG{eKglS{qbPWCU`}}xA3jGE1r#8T;*usI5mp`5)tXw2HAi<-&9uZB#94_a z5a%S$BQ8i>L~KYriFk@Alz=HN$&s+uF0-n8~ zvg_D^Q%p_Szscn+S2(^zM9Q^zx%nvb8_3y-5-)`-ZwWAWhJhwmaZ-umF9`S)!A zhpt$RVkXV}Za`Ug2DO79FAcVD^zVHaUfT)xcEhbJ;ZOVF{!aHLB$M>P!`;F9{e%76 z{i|Q}zyIOj!ObKS-n`uZX1l*}YjEwC!Orbos!^Y-&($=M3hcn4A`g_enB56%-xHaO zl<^3V7eB7)qG&mezhe5#ZrdIgr6g=I3e*d1%i%+XOM@jJM&S~*05|FtXRVGs%Y$yD z=iS1n*yIc~RirzNF4~_8J+RummrwL9pV34;*w_m9?b>ySJCaT+38>Xt!ouQ84%gQE4>lxk$V#oi=7HUc1=!!iz1{xCmBIGbUu3q0 z)sGDoqu=r2(YLZrfPiX~d8MYE7a5mwZnbImRivK2wm*JbKfM3*;oif?H}L#C z*Icwc%UN(O+pBk0h0c6GsNyzU$3wM0~8RCh;quH%(*rbTQKb&dMa6D+Di zOb$ac@w~_a<0MWP zDm3heFf0J`=v2b6y_SRK9*NpC7`4;0Txyyk)4gb8{hrWR*E_n(1eN2~zvlYTb?6)T wU#jr;a4Dz-^5j%il|(cBubx(kj!4Iu{=1whli|#&Ig-_~F`KA!|LFhy4>Ypy;s5{u literal 0 HcmV?d00001 diff --git a/student_system_final/aaa.py b/student_system_final/aaa.py new file mode 100644 index 0000000..4c1bbd8 --- /dev/null +++ b/student_system_final/aaa.py @@ -0,0 +1,39 @@ +from minio import Minio +from minio.error import S3Error +import io + +# 1. 创建客户端 +client = Minio( + 'localhost:9100', + access_key='minioadmin', + secret_key='minioadmin', + secure=False, # 本地测试用 HTTP;生产环境请用 True +) + +bucket_name = 'test-bucket' +object_name = 'test-object' +data = b'Hello MinIO' + +try: + # 2. 桶不存在就创建(关键修改) + if not client.bucket_exists(bucket_name): + client.make_bucket(bucket_name) + print(f"已创建桶: {bucket_name}") + + # 3. 上传对象,length 用 len(data) 动态计算 + client.put_object( + bucket_name, + object_name, + io.BytesIO(data), + length=len(data), + ) + print(f"MinIO 连接成功,对象上传完成: {bucket_name}/{object_name}") + + # 4. (可选)验证一下确实传上去了 + stat = client.stat_object(bucket_name, object_name) + print(f"验证: 对象大小 = {stat.size} 字节") + +except S3Error as e: + print(f"S3 错误: code={e.code}, message={e.message}") +except Exception as e: + print(f"其它错误: {type(e).__name__}: {e}") \ No newline at end of file diff --git a/student_system_final/api1/__init__.py b/student_system_final/api1/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/student_system_final/api1/__pycache__/__init__.cpython-310.pyc b/student_system_final/api1/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..728fc3ff2e0e9b3657d2f6a952c0c05e55db6aa9 GIT binary patch literal 166 zcmd1j<>g`kf^8y8vq1D?5P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;!?7kn3UTZlX-=vg$ckbnAi=@_0QPAu$N&HU literal 0 HcmV?d00001 diff --git a/student_system_final/api1/__pycache__/classes.cpython-310.pyc b/student_system_final/api1/__pycache__/classes.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7e2cbe939fe548071f3b645dbb86665da4438930 GIT binary patch literal 1733 zcmZ`(OK%)S5T5RN?RsZs{a8O^zySp8#U`8(LMSMX1QN2MI9x_6t;XB!c&wS7p?g-s zW-SGbxLL^|LL4F`dm;E>4sZw}-1rxL1#9ICH!k5>)w6a?Bzo1g)iu@CRbPMAneUGo zFn-G(ZeMf_;}=|<9|0^b!;}qT7|dWKF;Wtel!i1lLzAG5CRS>Pw${zWN!`%Zx|LMY zYFO2}os6Zmu$FqEm-?Zf24O%9PWFwk&g8B;{(9f$rSoMVoCjEmhOj4|5h3e6+YCI4*qs z8GhTV`T9XPN zz6hk@p&=UZ_xn{4t8cYlfAft?`A)Hwbz8?rUk~rzAAUO+-uYtq{o~=|`z=}Y81EKs zxg!gnwm0K$l(eEezSPo(a=D!EDDV7vH3%y!An2`tdc-4Q1{S;HBTO-0%xGop1nM?U zY!G4!gc{Qk+ubOI3)|umD|pn|0v1?#bdxJf#=E?OMV}5l1gA#*6;KfMZPK^<2H;Ek zX5V7uz-iGvXV2|BeV5UDh`G52=;4uK9>oHR3n&&rG^w(StcVh2$562ZjS%_-?s2b!7kN66T8NV_^kq;+ z^rBekz}z$YrW`NmQ;PM?b>k4Ibr-2shYcmQe*NK~B$Ys0(=03Vdb&wUwrB!1t+Kc? z$^f?#`D`HKW&pnJ4WW&M2e%vd+X61bfu z2#v=Jem+67Oc3d;NaxwiUIOz9%u#0EX=Z3|E+}_1f{w~#fo-b`7MPw2WqK`Rlf;3KdRNiN{2H^M;T9$tEJDUg$*iUN@l*bvGQ<%?$JnJjci zC=(c^%(x2zOqv7A%zK3f5c?d97MSz7`ZSr4N2>BRyhy!-zk_WgFN0_p&~DIjbHt&Z oxkx;RQcB97L#!vD{R5W2sY(B$7X6dj^bhKIPrSwwsklqzUxgf|kN^Mx literal 0 HcmV?d00001 diff --git a/student_system_final/api1/__pycache__/scores.cpython-310.pyc b/student_system_final/api1/__pycache__/scores.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ad4c0fdad63b7c3b28210a5a81f8b3788e019fed GIT binary patch literal 1164 zcmZ`%&ubGw6yBNL>~50XG;LEA!9O6E)_M{Vu@FTswKVmz1eQ%^qAB~!nGG~;3Tnlh zAmY9DQs_Z19((k^n5#(eT)Z{vo7qIuLuZ+{Z{GXnz4yI0iR+d$Sg-x#?GJ{geV2#X zCB64ya{+>A1ch3JJQQIMN4lpYX~Urr6}*Dd_0Wtg&r-S(+ELLfD!mYvqOw@_Y!P{mKEM6bEK;9 z3xHoF^OxZB*b8J)VQZw;)apw=fuB~_MR9H8@n+J`C=*tLrZgs8xR18BHXiJBXqxqs zxQ>L?q@3rf`HW^hX@k*jb`nM#YftJ}l$HK8B|%1os}7r#r%BA|?$s48fh&8wNA_3t z=uQy%aX;FJ5EV87`B6e>D0F}bdx{X4v^%=2bF!pffc*{jSrx=9lxd&P5D&E>I?|ik z30kjXW`Rc(Wu5JT-y^?-?0FKmetbS2eLNg} zIU2oxJNkM$Iz4RhtWRj1`Fy}L8u{H`9E7bP?X9*HE54i#@?7dDbDY7u((ucQ$!ehN zx)b{Syg4O>^Py2eM*^oy>LzT-jmz>T+;quph>wh>#^%60c$MYE8tfQ6~A08 zf=xI%*jKq_RXne;YO!l@`d1^&fM)d4p0kQfaG{F)2Ah`-S@mqv+?OZ4A$?0yTnDjU zUlLX~;2AWMVQH14WwIzy;V;4<>^!H@U^!tClLHsF>{mPBl*t}>E(wz5X(JOgaL?uP z4$aM+*)m{J-ZfeNymfdHLhr?ynv2lWex}$9BTaaw>YAaT$f)Mocj0mNLwXNEH2x4o qO?Qy|s>s9+HVtEp5&nZQ{*85K>{w>OIR9_KV{AC*j(rhV9sdPT6(6?% literal 0 HcmV?d00001 diff --git a/student_system_final/api1/__pycache__/statistic.cpython-310.pyc b/student_system_final/api1/__pycache__/statistic.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b405232618291f22e7c1db79fbce95c3337aba03 GIT binary patch literal 2349 zcmah~+iw(A7@u=yc6N5VyU-S)T$O7Xg)S|a5Mm4x44N2%!qcWnGu?BxuGw48%o^Kl z6R?Pous{?eBvrbJf{h|15)-NR#TWmE^JHSD+j;VV_@?0Zo!#v&R$!9(a?Uru?|zwL zJRa5H`MrAUy?#s6{=iG;13c|8ysk$yjcJVJv^+@>f@hkec|E1)jg*lOr9yc#Wh%a& z3+JtrMKrEYX{iX0%tV<{Biv*mX0kA|SfpyeEy}v!7GrUB3$X-SRi)hE))dJYY&Gv< z-S9?_Xsm~KWlYw~)|?GZkyK1+d=4}=u!OB;>&_DR5?5dPl&$sP;Rd!**=pb@+r$$Y z$~LntO3x~Ve!l6M#$I4sA46{gtCVeLI~01gLho#%cd>r9o7v!bOZSTk{Sw=w(A^5X zw}~F;h>WtNLhfUO3fZHOLx5~Wv!5MM(e$$DNzHyazY6u5JBX?|+)i`v56kB0^quiXLh zh5MKO{Q2S#UhZCo%bxvktlz$X#{hxRuk)i|JN}fM-L6}J2*608u#8U7KZ)X zH|tk#)W5IQubiv@Fjt?uG3S8T?5bKciA;Cx+WCNUJ?=rOQDB@a<8dl3uY{LmFIVK$F zw`6bvt^otm(VC0ruhi#ep^FtJjdf@}SnF0W572-L1~$PYtx&9QjZEql9jZ!>w@MgA z-x|7XLu>`1X9TmREzpi;7sx%pY8A0gp0d}B(J(xvJDxSB_7;!&G=x~+SLZ4lH`H{zMLsj%)w zJP7-F-sh#E7qkSyKGb~=GEWr(y zU`du@>AJ3PhGpwip+2^3QM;V2=;A)MvTM=LRw+ceb(~CCY=AFggM2w#4ZmyPcP-3y zfY-y^z|Dy)8)6&hBFBlnLglcDr!fZ}`V-}kb_UzbwkW%mVAs#KF0tFjlPaFUwzD0| zZWY)Ku-p!C7#d0Z#yjSI7Do29oD3=m60L@A6kFjw;@ln6Zc*)

r03f_nc#6E-y{`M}h?7vLK4;!qs)))Vg}7RlnIi`_f$d+>Q26^F`Km zCIZRb0bXm>1Bhl%wN5W|8h0MvJK4VQL%w`PKD&>+-kl`OlVwhZxPXCzgbNaO+yA53fUHq;S!IK8U4Jb?N*12DPoP|9s7i@oWF3@F>1xCs7c%T;mLhDNm=n~_s zT5uFYjEXbK149<4c|h5C0bYZ}fo}xP`!MBB5FZg=J4$NNnpPt~I^QuMheb5vjkwuK}` ze&pi+BZ|Pbi}ffrfLPGP5d8f5Hi*5i=3jc{<=vGj|46x%533mxvVHq*`|g!|m#|}U zNC9ywVU`BFE`$GGP#d#Gk}<^*tGX-Qq zZy-iiV<{h@FP8Eufih|hDAxkn-@ADXPa2;ZE3yR|UR_;o2z=D7#700t-_!XhYrOa) zJOUD;VjF_mJRrXo#*BwHiNO)0-~EkV1|CM+<{xqN+2DY^lF0MVmk`t$#iO@ zs-BH*C3MjB24Z9`RzhY$bSpuTR1JM}NhV>OoF10q`RRmqy>xOIJS;|F!n;I?)Pnf8*uvO!ZCHhzmAMVFW%dbB8EZnQxypm$jiVK;eUe; zR0;HA354{8qNt)rU{uPWzF+d3f1_6NaWcD>Bn_NHYW@St ClY|}s literal 0 HcmV?d00001 diff --git a/student_system_final/api1/__pycache__/teacher.cpython-310.pyc b/student_system_final/api1/__pycache__/teacher.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..07b36e3ed2a8a0f9eb0ae8ebb29e8cd1333f1234 GIT binary patch literal 1814 zcmZ`(&2Jk;6yKTs@JH6`r1?(zk(L5l0Wsx-P*qWpN+6+7n)I@=WNkd-WTRc%%&eu_ zI8v%0#3d33jz}dJP!4e6g484b0mr$bD&$;oDiq$E^|ncsj5W`1-u&L1_kQzcJC#b= zfN}80Pun*OhVdsZP7W6qAHtOD#4wn_NNgk|APEgKWK9<~8=3#x1b1 zHN(GtjC}i+D&4;O$-Pc5a>;pd5?>}PgG%zO9>WG zolTxL*am3jbsjdixLCRU8HB5hRv!r-ru@b7ewX30I@-O*Ww+CoTuqJ)pGGpxje}Ax z%|gl^Ho{-K51;(@&CxFhN8f(!Q{{98Z$%H3m4=&g;M8JptwA217zJ%49meC;V`v@2 zH&uc0R@jSEMK`&kF+axEQ|{=9MmtQn@*>&T;vpLumDLRaY{_TtQ##Q6H7R-0iDzJU{0M^Qb~-iPu4Q zi$zK-Qhr`G#T76NDzz_jWW;t<`Q@TXVLulBwkQxhjs)Mx}e#UtphOU3J;3<|Yo)`=E0V0dmm;wpf}H4u3Y zPUZ*8H*rhz{YnB}2FYncZ}A2SAH-m)*3(UYikzkiTlqj8J4<)cI4C1RD0b3;x%Nsz zSvcR!7&$+y43}qxIGJ(cQSlb6ATxL$Jmse|JMXH_peAz{*!yQKn3VGNX2?dssIMJo^q<@%EJ2?WLM6 zfr+1}@@1*ToA9CO#rzh2Xyh#rbEZpN>XJF)nXc)8M&aiW>lyt2M=5G?nA^S^8W literal 0 HcmV?d00001 diff --git a/student_system_final/api1/__pycache__/work.cpython-310.pyc b/student_system_final/api1/__pycache__/work.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..42857a7a291ca94e245c546fdf4db868bc8f9f00 GIT binary patch literal 1332 zcmb7E&rcIU6yBL`cb9fspp+jXMsB8;V$p*!#;9PT7lJ}!vT4#RodK%5-8!=yEWs0M zycjvCSKuHCF?!+P0sjX7fVrC5a5g3$eKWggBk{m&=Ixue-<$Wo_g)+1av2Sl^L6jx ztgdO_s{gjjPbw@|ij=i*RIEK1i+P+m7w$oSdI`@<^j-Q*-)h|IPq0b`ixivx$}wF{w=~YAoxdk7S;uH<2@_FxeiA zO>+q*NAe0&0L&2S@4*bve1aJy1%)XBW|#~CMkhrwOh(8k8GEHCkuf<#M-q>5a#nea zl8FVabnXb)Yb9Ou-JHLBKZrugggHxFv`M(g-C10mzx||6TVW$;iuApRvUUjxbAfUW z7O6f6*rQoD0M%HbVT~-6Qeto+j0kOp^4kofZb(JpgsCFz9vfdbr|L1(?k&kn(CCEOw^@mK+#yVm{psc5-S^*D*l^`nrWyJCTXZ;}laF7L!ISk8h z35RLLAQlC%i>$)MMN^j)C3+OZx<1v4{sx~uMet12BG9-b{#Z}^ODEz(jN=MO&P>H0 zm+{RhLOmMN@)3e#W8i|OMe?rB?uX9v_nobm-w)mM>*F$LXC!X%@0WA(d)AOd;-K6vei>W O2D0!3vh?F!M!x}y&`G%f literal 0 HcmV?d00001 diff --git a/student_system_final/api1/classes.py b/student_system_final/api1/classes.py new file mode 100644 index 0000000..607784c --- /dev/null +++ b/student_system_final/api1/classes.py @@ -0,0 +1,60 @@ +from fastapi import APIRouter,HTTPException,Depends +from sqlalchemy.orm import Session + +from dao.class_dao import ClassDao +from database import get_db +from scheme.classes import ClassUpdate, ClassCreate, ClassResponse, ClassListResponse + +router = APIRouter() + +#新增 +@router.post("/class/",response_model=ClassResponse) +async def create_class(data:ClassCreate,db: Session = Depends(get_db)): + if ClassDao.get_class(db, data.cid): + raise HTTPException(status_code=400, detail="班级编号已存在") + return ClassDao.create_class_list(db, data) + +# 条件查询班级 +@router.get("/class/get_list/",response_model=ClassListResponse) +async def get_class_list( + cid :int = None, + class_name: str = None, + headteacher:str = None, + page: int = 1, + size: int = 5, + db: Session = Depends(get_db) +): + total, items = ClassDao.get_class_list(db, cid=cid, class_name=class_name,headteacher=headteacher, page=page, size=size) + return {"total": total, "items": items} + +# 查询单个班级 +# @router.put("/class",response_model=ClassResponse) +# async def list_class(cid:int,db: Session = Depends(get_db)): +# cls = ClassDao.get_class(db,cid) +# if not cls: +# raise HTTPException(status_code=404, detail="班级不存在") +# return cls + +# 更新 +@router.put("/class/{cid}",response_model=ClassResponse) +async def update_class(cid:int,data:ClassUpdate,db: Session = Depends(get_db)): + cls = ClassDao.update_class(db, cid, data) + if not cls: + raise HTTPException(status_code=404, detail="班级不存在") + return cls + +#删除 +@router.delete("/class/{cid}") +async def delete_class(cid:int,db: Session = Depends(get_db)): + c = ClassDao.delete_class(db, cid) + if not c: + raise HTTPException(status_code=404, detail="班级不存在") + return None + + + + + + + + diff --git a/student_system_final/api1/scores.py b/student_system_final/api1/scores.py new file mode 100644 index 0000000..bac1107 --- /dev/null +++ b/student_system_final/api1/scores.py @@ -0,0 +1,35 @@ +# api/scores.py +# 本文件定义成绩相关的所有 API 路由 + +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.orm import Session +from database import get_db +from dao.score_dao import ScoreDAO +from scheme.scores import ScoreUpdate, ScoreResponse +# 创建路由器,前缀将在 main.py 中统一添加 +router = APIRouter() +# 根据 学号 + 考核次数 查询单条成绩 +@router.get("/score/{sid}/{exam_num}", response_model=ScoreResponse) +async def get_score( + sid: int, + exam_num: int, + db: Session = Depends(get_db) # 依赖注入获得数据库会话 +): + return ScoreDAO.get_by_id(db, sid, exam_num) +# 根据 学号 + 考核次数 修改成绩 +@router.put("/score/update", response_model=ScoreResponse) +async def update_score( + sid: int, + exam_num: int, + score_data: ScoreUpdate, + db: Session = Depends(get_db) +): + return ScoreDAO.update(db, sid, exam_num, score_data) +# 删除成绩,逻辑删除flag改为0 +@router.post("/score/delete", response_model=ScoreResponse) +async def delete_score( + sid: int, + exam_num: int, + db: Session = Depends(get_db) +): + return ScoreDAO.delete(db, sid, exam_num) diff --git a/student_system_final/api1/statistic.py b/student_system_final/api1/statistic.py new file mode 100644 index 0000000..75be79a --- /dev/null +++ b/student_system_final/api1/statistic.py @@ -0,0 +1,80 @@ +# statistic.py +# 本文件定义statistic相关的所有 API 路由(Controller 层) +from dao.statistic_dao import Statistic +from fastapi import APIRouter, Depends, HTTPException, Query + +from database import get_db + +router = APIRouter() + +@router.get("/ages") +async def get_ages_interface( + age1:int = Query(...,ge=18,lt=30,description="输入年龄"), + age2:int|None = Query(default=None,ge=19,lt=30,description="如果要区间则输入最大年龄"), + condition:int =Query(...,description="输入比较条件:1是大于,2是小于,3是等于,4是区间"), + db = Depends(get_db) + +): + module = Statistic(db) + res = module.get_ages(age1, age2, condition) + return { + "code": 200, + "data": res + } +@router.get("/class/") +async def get_class_interface( + db = Depends(get_db) +): + module = Statistic(db) + res = module.get_class() + return { + "code": 200, + "data": res + } + + + + +@router.get("/grades/") +async def get_grades_interface( + grades:float=Query(80,ge=0,lt=100,description="输入成绩"), + db = Depends(get_db) +): + module = Statistic(db) + res = module.get_grades(grades) + return res +@router.get("/bad_grades/") +async def get_bad_grades_interface( + number:int=Query(...,ge=0,lt=4,description="输入次数"), + db = Depends(get_db) +): + module = Statistic(db) + res = module.get_bad_grades(number) + return res +# +# +@router.get("/avg_grade") +async def get_avg_interface( + sort:int = Query(..., ge=1, le=2, description="1降序高分在前,2升序低分在前"), + db=Depends(get_db) +): + module = Statistic(db) + res = module.get_avg_grades(sort) + return {"code":200,"data":res} + +# +@router.get("/top") +async def get_top_interface( + top:int=Query(...,description="输入排名"), + db = Depends(get_db) +): + module = Statistic(db) + res = module.get_top(top) + return res +# +# +@router.get("/get_time") +async def get_time_interface(db = Depends(get_db)): + module = Statistic(db) + res = module.get_time() + return res diff --git a/student_system_final/api1/students.py b/student_system_final/api1/students.py new file mode 100644 index 0000000..81a886b --- /dev/null +++ b/student_system_final/api1/students.py @@ -0,0 +1,48 @@ +# api/students.py +# 本文件定义学生模块的所有 API 路由(Controller 层) +from fastapi import APIRouter, Depends, HTTPException, Query +from sqlalchemy.orm import Session + +from database import get_db +from dao.student_dao import StudentDAO +from scheme.students import StudentCreate, StudentUpdate, StudentResponse, StudentListResponse + +# 创建路由器 +router = APIRouter(prefix="/students", tags=["学生管理"]) + +# 查询学生列表(支持按编号、姓名、班级等条件筛选) +@router.get("/list/", response_model=StudentListResponse) +async def get_student_list( + sid: int = None, + name: str = Query(None,max_length=4,description='名字的模糊查询'), + cid: int =Query(None,description="根据学生的班级id查询"), + gender: str = Query(None,max_length=1,description="选择项(男\女)根据学生性别查询,查询男同学或者女同学"), + education: str = Query(None,max_length=2,description="选择项(硕士\本科)根据学生学历查询,查询该学历学生"), + page: int = Query(1,description="查看的页数"), + size: int = Query(5,description="查询每一页的数量"), + db: Session = Depends(get_db) +): + total, items = StudentDAO.get_list(db, sid=sid, name=name, cid=cid, + gender=gender, education=education, + page=page, size=size) + return {"total": total, "items": items} + +# 按学号查单个学生 +@router.get("/{sid}", response_model=StudentResponse) +async def get_student_by_id(sid: int, db: Session = Depends(get_db)): + return StudentDAO.get_by_id(db, sid) + +# 按照用户输入新增学生 +@router.post("/create", response_model=StudentResponse) +async def create_student(data: StudentCreate, db: Session = Depends(get_db)): + return StudentDAO.create(db, data) + +# 更新学生信息 +@router.put("/update/{sid}", response_model=StudentResponse) +async def update_student(sid: int, data: StudentUpdate, db: Session = Depends(get_db)): + return StudentDAO.update(db, sid, data) + +# 删除学生 +@router.post("/delete/{sid}", response_model=StudentResponse) +async def delete_student(sid: int, db: Session = Depends(get_db)): + return StudentDAO.delete(db, sid) \ No newline at end of file diff --git a/student_system_final/api1/teacher.py b/student_system_final/api1/teacher.py new file mode 100644 index 0000000..2856199 --- /dev/null +++ b/student_system_final/api1/teacher.py @@ -0,0 +1,46 @@ +# api/teacher.py +# 本文件定义老师模块的所有 API 路由(Controller 层) + +from fastapi import APIRouter, Depends, HTTPException,Query +from sqlalchemy.orm import Session + +from database import get_db +from dao.teacher_dao import TeacherDAO +from scheme.teachers import TeacherCreate, TeacherUpdate, TeacherResponse, TeacherListResponse + +# 创建路由器 +router = APIRouter(prefix="/teachers", tags=["老师管理"]) + +#查询老师列表(支持按姓名模糊查询、是否班主任) +@router.get("/list/", response_model=TeacherListResponse) +async def get_teacher_list( + teacher_name: str = Query(None,), + is_headteacher: int = Query(default=None,ge=0,le=1), + page: int = 1, + size: int = 10, + db: Session = Depends(get_db) +): + total, items = TeacherDAO.get_list(db, teacher_name=teacher_name, + is_headteacher=is_headteacher, + page=page, size=size) + return {"total": total, "items": items} + +#按老师编号查单个老师 +@router.get("/{teacher_id}", response_model=TeacherResponse) +async def get_teacher_by_id(teacher_id: int, db: Session = Depends(get_db)): + return TeacherDAO.get_by_id(db, teacher_id) + +# 新增老师 +@router.post("/create", response_model=TeacherCreate) +async def create_teacher(data: TeacherCreate, db: Session = Depends(get_db)): + return TeacherDAO.create(db, data) + +# 更新老师信息 +@router.put("/update/{teacher_id}", response_model=TeacherResponse) +async def update_teacher(teacher_id: int, data: TeacherUpdate, db: Session = Depends(get_db)): + return TeacherDAO.update(db, teacher_id, data) + +# 逻辑删除老师 +@router.post("/delete/{teacher_id}", response_model=TeacherResponse) +async def delete_teacher(teacher_id: int, db: Session = Depends(get_db)): + return TeacherDAO.delete(db, teacher_id) \ No newline at end of file diff --git a/student_system_final/api1/work.py b/student_system_final/api1/work.py new file mode 100644 index 0000000..e706649 --- /dev/null +++ b/student_system_final/api1/work.py @@ -0,0 +1,31 @@ +#这是学生就业系统的子路由 +from fastapi import APIRouter, Depends, HTTPException, Query +from sqlalchemy.orm import Session +from dao.work_dao import WorkDao +from database import get_db +from scheme.works import StudentWorkCreate,StudentWorkCreate1,StudentWorks +router = APIRouter() +#这是添加学生就业信息接口 +@router.post("/create") +def create_student(student: StudentWorkCreate,db:Session=Depends(get_db)): + u1 = WorkDao.add_s_w(db,student) + return u1 +#这是获取学生就业信息接口 +@router.post("/post") +def get_student(student1: StudentWorkCreate1,db:Session=Depends(get_db)): + u2 = WorkDao.get_s_w(db,student1) + return u2 +#这是更新学生就业信息接口 +@router.put("/put") +def put_student(student2: StudentWorks,db:Session=Depends(get_db)): + u3 = WorkDao.update_s_w(db,student2) + return u3 +#这是删除学生就业信息接口 +@router.delete("/delete") +def delete_student(user_id:int=Query(...,ge=1,le=10000,description="填入合法学生编号"),db:Session=Depends(get_db)): + u4 = WorkDao.delete_s_w(db,user_id) + return u4 + + + + diff --git a/student_system_final/dao/__init__.py b/student_system_final/dao/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/student_system_final/dao/__pycache__/__init__.cpython-310.pyc b/student_system_final/dao/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e6199666e0e16429c50185fb02f7f417d1ff22f9 GIT binary patch literal 165 zcmd1j<>g`k0+DU;Ss?l`h(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o71s$aS%bF|aT) zET}BW$j^&;x^~&~Df6GNTljoJ+w;x4pYNU@Q(RJ-lA2c%UtC#SlA0TzmYJ8B6O)pd j9}^#+nU`4-AFo$Xd5gm)H$SB`C)EyQLopMOU||3NpBODl literal 0 HcmV?d00001 diff --git a/student_system_final/dao/__pycache__/class_dao.cpython-310.pyc b/student_system_final/dao/__pycache__/class_dao.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c094e1d26a6142ed704964561bf8fd21d01e3415 GIT binary patch literal 2786 zcmai0&2QaA5clr-D}EnM(j-j-v=TxE0}7>pgsOrnwJH*aTp}({ku2A{FLAKnOLjMh zMDD3oZ%7H#hsd*_eXD?(BK08U((Sv&7J9~JwwNY|`(#5=qTv&TEb zkoWnOXC7G1)mB5w=lO!Qh|cV@$gf&y=ZtiTFI#DMCWX`VhCW~6*X)~q^Cq&VS>@NQ z^a}5Qi{3J!#s4rJ8_FLW7m%kJ1%Rgm0~5e}08`xsqMeHD5||VwgXwa@=?~r$S~6nu|<-*jHm4TLf1I)twQ@-^k{JkXZqTH^)-Il?!Qq73*(d_jMIT( z!GKy=&w**df}}z)6Y|8bh+M9GfZ71HGAeI2GDx;YkIA@^`4wwq{&6sIo&+Ed(H>kg zS3#<-I+eHNz$&UdpdHW&tDp*pkf3rEjuLm}b$HYXw}u=#sg-&*>%44yFw!O*OD<&c z_|W*{;ZO-}yduX$WNA^vbG1ijS!+$*y>wd`SLH{-e#v-xtkc4HIV77p@B04Kw+W`$ z+i(_z(OH2Mn}?*TXGq>7AvwBsF(TF~!)tdske@mq0bb_(V;A$Nc8GVWL*50;nA8Z* zrArUb3=XJM=0i}lDYHh8R?Zx7s&XdhvEq0zZF1ZJMmxu(f~qs2P-CcyIGjw=UAF65 z>RIYr8gTNn3zdd$#IB)GV_aKZ7<$~_79$82)Do;`5Q$`}uahmZa9 z0K=x3s+p4f1l8Y+rLp(|v|3meFUQg-XBfHDfjFjE?!lskg;lJMV#Ri;T&O7Y5|+T+ zWpWi(@IGOXm5_tbLl__=8?o0yWm^DVCbhw7XIMVc^^JNTWgj3xzev2l5=+1Q49Vw6W?5%B>@d~| zsHU*2gwQ~j2<^jkZxGs>CzJv2!wgml?XD85zY$09zhS>f3;3r{9@@5M`ZK}$SeEvn xrU#frv7X`o4Wa5=-&bfQra}wGp466yOAcwmd$n)A#>gpjVAtuAF4W*f`X4iSTa^F+ literal 0 HcmV?d00001 diff --git a/student_system_final/dao/__pycache__/score_dao.cpython-310.pyc b/student_system_final/dao/__pycache__/score_dao.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5b0e3fb85f0d7eb21ca4833947d8a33660e34151 GIT binary patch literal 2206 zcmZuy-D@0G6rX$NV`sn8G>xs;DiIN!2tf;i6p?D{$5RwjUzWfy*?YH{IJ2AFxeG~{ zzL-*q7|lZjL8V#5(m+~8AF8C%|Kq-z&Dtk@@wuLJXLhsM_AYbpx#ym_bI$Ml&e>MA zS~6g`{_UlIUBmbbH^ak(%|&>UPhesOBaso48X+jth{k5k)Up{_v0byZY(-97s1>wq zM{ZoK72{H^M2rs%=CHzbgB3Ptt<2mx!z(_5dkv4M>W5dZeEi;OoiEF<)dYnVG?@=; zVU8zBrn2YiEx|pi%38Q2cp!Pc`E;4VrjEA_k0NX?!jpUf6E|vv88ymHM!3Z&x0%W9 zhQlmoU$-_$%{e-0SlU%H^v;>^IwS9bxYe3xonZm*7d>g()?53`sgeXSe-!S34&@rx=sVUB;=A0p2Mw!X1P5L?U?Ab>IZVI@D7dQZMko>~C}=!OU^a$K>;&_qhUl{oekq`9!uEZ%RK|OC*o|M%WCZc^0(h^;JGdGs|nLc$G_kVa*TO7+jiEV0wjG zgg&-lu8{SKKK3&M!#cXyA1GsN8uDonh9Dlv1EAV@sE5>2b z5Q&p0X=o-uQf^ByF2KPIDKm&7j}C!@aA-`#X*3_poy=oD1G>b4$)!^e()yXvU~)TU zK}7_|;yOkptcanwaw;uZIhlY^PoWb{shG~Flmhj>GZ@fs$%fVb!DbGUOAtxc$fBS3h;X{!vuH9#}Wvq?iPSz!Z4Z(d-;& zuQn2=&>Xp-UsPtmm~!f^I1Z&M2;LApS?sg=ESM>quZF;O{h5&@I(6Nxo(Ho8&(E6{ zvB)HG9-pQq;*t{V)=vylnOUn+pVp8_OkRH=CIf1hMqmdTC95U zB222B8ACP7AmgzH1Ia92f(i4ei_)bol%os3vEkse*Pm#DgMg>ueF=f~gSZC$JT-j^ z!J9d=tRZGWMPjo9X9tdF`PIR^fJdXPsphf;Ut>SwKlZ?gOa2CifXIwd=gI74HnUz; zxxU{FV($B@s3^t5x~cnL(Otv+e#Ef^+g`9 z>29vZjubO35o_OSr!-Y&2Avptc=k_FP4Hblqk&5@ueHM(_ow)(+_y4J-o^xJN>peC LC{dx~WWxL(%Krj@ literal 0 HcmV?d00001 diff --git a/student_system_final/dao/__pycache__/statistic_dao.cpython-310.pyc b/student_system_final/dao/__pycache__/statistic_dao.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..412b1804ee0e4d4e4703a455c1f86630bb21496b GIT binary patch literal 4677 zcmZ`->yIQ=6|Y-$tGcSXd!}c0S$25{CMdM%%Ay9u$x6byh{nNWQAua9tm#`bbZ>R{ z%&qE$nN%kxyF5OCpst{14c&=I7Dd)T6v4;;alh*9?0hoOY@)bX{GD6f(+{C1_td@j z+~+yJ^SIL~mwf}j^x4;%H(zfUf1}3a&qCvVlw<`&7=pz{i`5vTx*3}-t7f%$jkoNY zt^2IlX%%V(UFWge@@k&0+p*s&){46B#HCibR%XV7hA0U4tRdVpW^GP*Cyc7Ui+zkL zQ|`m-X`|B)o3G=K`vxF6K!6Q53hYSI_>Ig>^&hnZgT;X9vLHMGGuPaL6 znxZV`!1ctuZdJqrTE18m`!J>`_KWNAEr|oT)AhZZs#AFYB_Taz zEHeU#7L(XA?qQ0Rs;PJq#jCOi{slvp@wxIfkYo3qyzAb(kF0N|k9XQ9x8L~H&be21 zemmHC@#&qn-rITam6J&>mmt|p(x?@zHXzKCBJ6-MJWPPr;q^`B20^3UNP~d(Na#d9 z+gjW^^WhO2idc(|XnMEu>YcV|kdEpcGe$oWG8KKNU!sy3O{33JbHI8$Gn4x=OR!U> zJecvmm6}bSu~U4&`u4!+*_nO90N(`vjtRao!?(b{cY=?#$MXf(YuFg`O+CgL?V`Wt zDdWuljjuY(y9{UDrMvGE=DRn7T>i_Cx1V}-_uS7ezxn1r{`B1LGtXao>Ef`H?p!Ts zttfk=8_7*sK$mh>8*v&*WkFORaV%-Msv}GI$O@4KB8wo(f{qm1&`Qn89Cf>EQ5s-= zLapRhkdn!n%l0!~asLTgcCUc?{6DUFE90DhFsZH4Hr@lT3(#rU$J@KW5%s#_%1%3J7}xw(7)L?9(`~0UPuFFbMzzvvG{Gni zTg0k*8mkgc-pG+^)v=r_$St+&sU-2qgCNR^qqcIw^>qlTTGqg=xfmSK1(hSCq#LKo zlAR~y9T;CL0ObLYEN`cl+X~xyB%P~0Jfis(WZX-JaZK5o=iugTxOteC8zY**&LM=((Al zIjd&R%e;)AW-_AonjtK~&vQ5!Z^h%I2{O`dsmc{^hpk9kgz{;Gh|;hT%P-K7dqDsMH+nK`1(0>F z@O{*KV8SjnAV}|$yqdDLjp(t;j>DBG&JEOElb!B*u(GL~$HUW&_L_2&?#eg_$$MxC zvQ7C#T8B3~jkaR-F}M`ZZTWNfg+&i-*uQ$v zIRM_)!D-x%w?KN-k?9n23AKC3eHV=xnv>!p6`1Jfgnd8v~+%_91W8gnJ$ zAbT+ppvr_fn0}7AIbyNpjC`zJyp2F4~@D`q43v%yaUZH#Kyzs`(yRTjGP~HCHTid^QX8YNv zC4p%w@KCg*z@>vDAuB`rehAGA=Cb@M+FEyrhV02%ExJo_*jf?c(Wfv>M?crt`qZ=r z=uo+mCqrO9?UAY}Dbr8|8J&(~63P8&edOunLv$KSYV(79eXpj&B4t7H8z9e6Wf|mn z<3-%AOObOXMzSRzlWRvv4D+ zEl@-JOT_&$5z6bdH zj_6d}JZblkN9N8sL;gta7%ta7k7OTNU9B{FsA&KBNt{Y!xl0Lio_k;V!H>3Ie77`{M8Z{?5-Yz5M&#m*4JclX&Vk+b_I>VS4!GmtMbg@$KrugxxZcIC>q|dMN0?3lRe?MyCO!vVLYS*CAE=-| z^J<0P%FO?AhqF20WNTsCG%;(+*64&JI<0mxGk7q(H1l_v_I#WaKd|!DMyE9k`T=0$ z5x@_UzeA*_2SGMYa27I(hm_!S30L_Gv>|4c@{_+p3iPhbGf$GUwk73tkY8$9%WqTX zo>>iZo;>d8gy#|Bf0xLNjPyf^1o=}ilLH`pC?uGUXuX#ky8h%6a*XHFwQx09;+&=(M}~fQ+YEH%0T7kh)|*>zeVJGL{^B552H!?9DMYNMse$IIU|0&Vv*GKrUvnzKg7tK+M PDEduGQY{Vt7OnpQHK$)c literal 0 HcmV?d00001 diff --git a/student_system_final/dao/__pycache__/student_dao.cpython-310.pyc b/student_system_final/dao/__pycache__/student_dao.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4e7183cb7c8e5e72dcfdaad09fed1cf8c93f22ec GIT binary patch literal 2183 zcmZ`)&5smC6z{73?wQ$Lc2`4)AH;y#YF67JRbs!15q zn;0S9FdjIVC}AcsDhIrHA>lvpPpGSs4Hs`-yy$z?Jv#$pCH3ajt5?7KaUsb1>z{AehBSVU?sy2ZpnS!UvyjJ|+;; zW6Zdw>`E4ZG8-*WF!b{<;iVquGSh1;r|gH5BV0v@=Y%;X^XN&P5vyt{SMc&~C1HDeqb0B{2SV5yXY}w%$4Y?y2Ee z?F{-`kM93?aQp7TFVll>zB>5z;labZTe7akM2;n#O?r7hEw)%XINShzV>s5qHdjfJ zONG?R7eG93J9LFONtLRROtJyv+GAX$c@g_2nTB4`ffF?WOQ31DmkX%`27k|j&~R*{2L}Cls<~ zSI|%d^XE)0^XoR2g(5cb#a>;%Q3=qCgpJCfFc9sOLB(c+63fsRyeGKai5sx5!RN(E z6j)jdK)uYoW4JG|6j!N7BB+1}kset4`D|bx;WYH00i~k5@F+8Si|pF~g(v_u zu@&8IUWbWW!8>5!c?eValc0ixOly#r@fGIRvI5@PWYmYQibL@_-1{tEwKpx+W zItyIVO@Z%j?9O90{M9(#ge`Fb#nU_i*h*fjCq6UEI!F_rDT`->rh_we3eF-IO+wqi`wCgL{{^+@_P_uD literal 0 HcmV?d00001 diff --git a/student_system_final/dao/__pycache__/teacher_dao.cpython-310.pyc b/student_system_final/dao/__pycache__/teacher_dao.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cf46dac8b3dff5799559796b595af0cbfcd8bda2 GIT binary patch literal 2092 zcmZ`)&5ImG6z{73oZgxJatSdQiE$&g%A$f0Bm^ZLd5^&{#aPn|P}CV$pm3{AnAN7-W(&;WPDV{O?k&=G!3GxQb1!pPz#6w5 zu=-u%@v#j(u6k!^~qXHfwHXj&Hz!j?EiulM%qVsKasQS3mr8^@u<|M_6r5 z*+%MuGFbsAnD!Oe64S1%p{2-(45=d9HX}Fai0ru)5oapb*qouuXhnVi67Jd~@Pu0` zmdCeVMaN&bLw{uLd0-D9QUfA}6~sGjRnC$Hr0khZ-lFrmN6g{Y<7 zojw->;ebJVSzahEw38Ldrf#a5ptzHiTsuX6gX`H`##=mL<16i^-F`>upeq;`@y0-h zlaF$yy>6CCuC!a^Wv;ZH6h#yWERdK(v4Fqn^pZ`8F7sV3nrLuUS0#mZbHz(}-x4o@ z@yRt1SKnWM`{KLr^ag6H+gU$&@blrFdxsB4hu?jD_}k;d$M@Ey>NDO^u^dSFHqP=+ zQmnJ2yFSSY^p)N~2b)~QMJ`nfqRM#?r>H~D5Qof@fGoq_ePOM}4!o{Ryu}iDrWC|v z;p`yIhStlVJWFc@v;rxPp_dL_Ac0m?o>d;B%r@jYcWvhG)2~Q{#CSC^`5ow_KK9FB zUwnD+=$mtWtl7CgAMGDJ`2OI>UtwZqq)Jp@#%Y&v?J=&Byoh{LKtrWKXeMDX3z~Mb zTu3D_`TKTF0ix0VxHP89wK$9R27=xg#5sErjuPADJk)3jYP7p_qBh1&J20!s|5xWC zL{QMoxmA%N8CgG(Z^<5IfIFs8HM@cVAXqiZnlE@JxZH}yU@ySWi&s%#J52%gQuF4#0#=Fbw@5t_LI;G1bYTihcJ~t3@Rwds0O))FDAd4 z7SP6VzXPKaHNXglvHQ(A$eF5W=lp}^va6%@z08Vx7NpuH%^;vd{(1S z`&j}%-pkE=>RGu{BnA9yEC(xHQJPeA%e4E-WL&ZKdQPGfpBQDGpvlej!*kNo!KE7h QWh7x-$tG#id9rB#3sWNFy#N3J literal 0 HcmV?d00001 diff --git a/student_system_final/dao/__pycache__/work_dao.cpython-310.pyc b/student_system_final/dao/__pycache__/work_dao.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..370487d559c645a23c48d38ceb0dbb251d9575d0 GIT binary patch literal 2465 zcmZuz>u(fQ6rX$NxwEs|hZSEWphnC_QwyIAF-iicpBj>4G@I%;_Rf}RXLgr6Gr=Xx z2W=q)gT+7~Af~P15sXkpW6=`%C;W83+U>S~fM1E{+}U=Q$87GIbIv{Yb$-8lW^09l zt-$loM>nT7@`~~=8oiGS#y)6q6$Dcl36+SH2|=BPG*Zi|)YVXn^s+8>Ei@vtY)V}Z ztteN{N!(f52@#&H(2F8+<`PBr?{oIF{ zgwx}S#bA$>1?--{g?k?ZjD65z4#HQ;gehg}tBm*>qrP6zn98(SZHAPMEw2e)of*<= zZFzIxHJK&7wy*kmmSZ-{Gv};YA#%Qg??6nE_08%qUxD>QDh7m!`#<2-1Z7`{fjB#p zdkmazP_5J^C~R!=LC|z)`=P}nAQAv8P?}_cEGpN?x8wwEDhsqp7Xe7n)J26TiN?qb z+7#APN7FtS*IK^2w!G3hv#@shT>VF@d(ZBABRNv5j<;^#XkVCb-&t&*JJtSerM)sg zzInX35hs4+R)VS*jx(<|F3$_faJ?Z+Sl5l+W4O^6Sv;uP#Dbqjj`wx4HQb4LB0YEt znV!!;ffOhSStJWIQ4=zyHK9#Y&~(srsTrUd({x6KD05LcK@)2;T~oO!yGcRjK|0V1 z&~#`9qgRbAnS-#(>Vw6#ua?&4udgrtnB}u%q?o2G0j-9-`sB~8xqF?dk;H3PPp@D6 zsZ|A2wm1o+F3K8$22O{!45zZqKhadvD;X0cU47sI#uQ1~W8jvw1DPUP( zxwG_ZQnE({8Q}zu5!?l)ZlEU22x^-*>8CG&1)S*6X8CS=Wp4GsowW;pW~|z{0pTfT zbN%o0t&`U~akp>4n2igU*O!)VQIU@mFG*u}0`9Ren4fq-SSoT%zvKi*!f~90<8u53 z6ayfD1Yylf_>1V+i2^H6IVW!>BF}fA6HCw|z?0x{-0ifEbseF96{6#vAhuJB*w8Fe zlvjDMNA?p(JwCX3vActZvqUYNB1(x0I_V1<`oc_OpSuBjgeAz3EtY%^2B6Wo`57+` zD4*^;p*B@y%rxaMZ}n?X4WwVPNQY=Bmrc!uJKiLKqKYU|D5HR+3A}*9FOf7yIJg<4{{vQD_J zuw56v3~A_t?zryJ)C;jZpoN4BCL$kdKI2%5xP{_b6j;6aD=2a(-bA5+5Gs63_#QO7 zo0S??4i0}<6trTjNR~p$5T)i2p*FN_yNK)`g>R>YJd@l+t_ri_!Di}#%#X0@4dzv0 zYuSo+d^GgJi6eg0$m(IS>lm)_NN&BHegB4$^jQgYVjSX2Pn?}h9z~uE_xZE~2 age1).all() + + elif condition == 2: + q=stu.filter(Student.age < age1).all() + + elif condition == 3: + q=stu.filter(Student.age == age1).all() + + else: + return f"输入错误,重新输入" + else: + if condition == 4: + q=stu.filter(and_(Student.age > age1, Student.age < age2)).all() + + else: + return f"输入错误,重新输入" + return q + + def get_class(self): + # 查询所有存在的班级cid(去重) + cid_list = self.db.query(Student.cid).distinct().all() + result = [] + for row in cid_list: + cid = row.cid + # 当前班级全部学生 + all_stu = self.db.query(Student).filter(Student.cid == cid).all() + total = len(all_stu) + if total == 0: + continue + # 男生 + man_list = [s for s in all_stu if s.gender == "男"] + man_count = len(man_list) + # 女生 + woman_list = [s for s in all_stu if s.gender == "女"] + woman_count = len(woman_list) + + man_rate = man_count / total + woman_rate = woman_count / total + + result.append({ + "class_id": cid, + "total": total, + "male_count": man_count, + "male_rate": man_rate, + "female_count": woman_count, + "female_rate": woman_rate + }) + return result + + def get_grades(self, grades): + stu = self.db.query(Score).filter(Score.score > grades).distinct().all() + result = [] + for st in stu: + result.append({ + "sid": st.sid, + "score": st.score + }) + + return result + + def get_bad_grades(self, number: int): + # 第一步:统计每个学生不及格(<60)的记录数量,筛选出不及格次数 >= number 的学生sid + sub_q = self.db.query( + Score.sid, + func.count(Score.score).label("bad_count") + ).filter(Score.score < 60) \ + .group_by(Score.sid) \ + .having(func.count(Score.score) >= number) \ + .subquery() + + # 第二步:关联学生表+子查询,拿到满足条件学生的全部不及格成绩明细 + bad_list = self.db.query( + Student.name, + Student.cid, + Score.score, + Score.exam_num + ).join(sub_q, Student.sid == sub_q.c.sid) \ + .join(Score, Student.sid == Score.sid) \ + .filter(Score.score < 60) \ + .all() + + # 组装结果:按学生分组,一个学生一条,里面放成绩明细 + result = {} + for name, cid, score, exam_num in bad_list: + key = (name, cid) + if key not in result: + result[key] = { + "name": name, + "cid": cid, + "bad_detail": [], + "bad_count": 0 + } + result[key]["bad_detail"].append({"exam_num": exam_num, "score": score}) + result[key]["bad_count"] += 1 + return list(result.values()) + + def get_avg_grades(self, sort: int): + q = self.db.query( + Class.cid, + func.avg(Score.score).label("avg_score") + ).join(Student, + Student.cid == Class.cid) \ + .join(Score, Score.sid == Student.sid) \ + .group_by(Class.cid) + + data = q.all() + result = [] + for item in data: + result.append({ + "班级": item.cid, + "平均分": float(item.avg_score) + }) + + if sort == 1: + result.sort(key=lambda x: x["平均分"], reverse=True) + elif sort == 2: + result.sort(key=lambda x: x["平均分"], reverse=False) + else: + return {"code": 400, "msg": "输入错误,sort只能填1或2"} + return result + # # + def get_top(self,top): + stu=self.db.query(Student.name.label("student_name"), + Student.cid.label("class_id"), + Work.offer_time, + Work.company_name, + Work.salary).join(Student,Student.sid==Work.sid)\ + .order_by(desc(Work.salary)).offset(top - 1).limit(1).first() + if not stu: + return f"错误排名" + name,cid,time,cname,salary = stu + return {"名字":name,"班级":cid,"就业时间":time,"公司名":cname,"薪水":salary} + + def get_time(self): + result = [] + stu=self.db.query(Work.sid, + Work.open_time, + Work.offer_time).all() + for item in stu: + time=item.offer_time-item.open_time + result.append({"学生id":item.sid,"就业时长":time}) + return result + # def get_avg_time(self): + # result = [] + # stu=Query(Class.id.label("class_id"), + # func.datediff(Student_employment.offer_time, Student_employment.open_time).join(Student_employment,Student_employment.sid==Student.sid)\ + # .join(Student,Student.cid==Class.cid).group_by(Class.id).fillter().all() + diff --git a/student_system_final/dao/student_dao.py b/student_system_final/dao/student_dao.py new file mode 100644 index 0000000..f2435de --- /dev/null +++ b/student_system_final/dao/student_dao.py @@ -0,0 +1,65 @@ +# dao/student_dao.py +# 本文件封装对学生表的所有数据库操作(增、删、改、查) +from fastapi import HTTPException +from sqlalchemy.orm import Session +from model.student import Student +from scheme.students import StudentCreate, StudentUpdate + + +class StudentDAO: + # 多条件查询学生列表(编号、姓名、班级等,条件可以叠加) + @staticmethod + def get_list(db: Session, sid=None, name=None, cid=None, + gender=None, education=None, page=1, size=10): + query = db.query(Student).filter(Student.flag == 1) # flag=1 才是有效数据 + # 传了哪个条件就追加哪个过滤条件 + if sid : + query = query.filter(Student.sid == sid) + if name: + query = query.filter(Student.name.like(f"%{name}%")) # 姓名模糊查询 + if cid : + query = query.filter(Student.cid == cid) + if gender: + query=query.filter(Student.gender == gender) + if education: + query=query.filter(Student.education == education) + total = query.count() # 先算总条数(分页要用) + items = query.order_by(Student.sid).offset((page - 1) * size).limit(size).all() + return total, items + + # 按学生id查单个学生 + @staticmethod + def get_by_id(db: Session, sid: int): + student = db.query(Student).filter(Student.sid == sid, Student.flag == 1).first() + if not student: + raise HTTPException(status_code=404, detail=f"学生 {sid} 不存在") + return student + + # 新增学生 + @staticmethod + def create(db: Session, data: StudentCreate): + student = Student(**data.model_dump()) + student.flag = 1 # 新数据默认是正常状态 + db.add(student) + db.commit() + db.refresh(student) # 刷新后能拿到数据库生成的自增学号 + return student + + # 更新学生信息 + @staticmethod + def update(db: Session, sid: int, data: StudentUpdate): + update_data = data.model_dump(exclude_unset=True) + db.query(Student) \ + .filter(Student.sid == sid) \ + .update(update_data) + db.commit() + return StudentDAO.get_by_id(db, sid) + + # 逻辑删除学生(flag 改为 0,不真删数据) + @staticmethod + def delete(db: Session, sid: int): + student = StudentDAO.get_by_id(db, sid) + student.flag = 0 + db.commit() + db.refresh(student) + return student diff --git a/student_system_final/dao/teacher_dao.py b/student_system_final/dao/teacher_dao.py new file mode 100644 index 0000000..2f9d85f --- /dev/null +++ b/student_system_final/dao/teacher_dao.py @@ -0,0 +1,59 @@ +# dao/teache_dao.py +# 本文件封装对老师表的所有数据库操作(增、删、改、查) +from fastapi import HTTPException +from sqlalchemy.orm import Session + +from model.teacher import Teacher +from scheme.teachers import TeacherCreate, TeacherUpdate + + +class TeacherDAO: + + # 多条件查询老师列表 + @staticmethod + def get_list(db: Session, teacher_name=None, is_headteacher=None, page=1, size=10): + query = db.query(Teacher).filter(Teacher.flag == 1) + if teacher_name: + query = query.filter(Teacher.teacher_name.like(f"%{teacher_name}%")) + if is_headteacher: + query = query.filter(Teacher.is_headteacher == is_headteacher) + total = query.count() + items = (query.order_by(Teacher.teacher_id).offset((page - 1) * size).limit(size).all()) + return total, items + + # 按老师编号查单个老师 + @staticmethod + def get_by_id(db: Session, teacher_id: int): + teacher = db.query(Teacher).filter(Teacher.teacher_id == teacher_id, Teacher.flag == 1).first() + if not teacher: + raise HTTPException(status_code=404, detail=f"老师 {teacher_id} 不存在") + return teacher + + # 新增老师 + @staticmethod + def create(db: Session, data: TeacherCreate): + teacher = Teacher(**data.model_dump()) + teacher.flag = 1 + db.add(teacher) + db.commit() + db.refresh(teacher) + return teacher + + # 更新老师信息 + @staticmethod + def update(db: Session, teacher_id: int, data: TeacherUpdate): + update_data = data.model_dump(exclude_unset=True) + db.query(Teacher) \ + .filter(Teacher.teacher_id == teacher_id) \ + .update(update_data) + db.commit() + return TeacherDAO.get_by_id(db, teacher_id) + + # 逻辑删除老师 + @staticmethod + def delete(db: Session, teacher_id: int): + teacher = TeacherDAO.get_by_id(db, teacher_id) + teacher.flag = 0 + db.commit() + db.refresh(teacher) + return teacher diff --git a/student_system_final/dao/work_dao.py b/student_system_final/dao/work_dao.py new file mode 100644 index 0000000..21d9c3c --- /dev/null +++ b/student_system_final/dao/work_dao.py @@ -0,0 +1,80 @@ +from datetime import date + +from fastapi import HTTPException +from pydantic import Field +from sqlalchemy import and_ +from sqlalchemy.orm import Session +#导入表模型 +from model.work import Work +#导入请求模型 StudentWorkCreate,是学生就业信息表的第一个请求模型用于方法一, +# StudentWorkCreate1,是学生就业信息表的第二个请求模型用于方法二 +# StudentWroks,是学生信息表的请求模型 +from scheme.works import StudentWorkCreate,StudentWorks,StudentWorkCreate1 + +class WorkDao: + @staticmethod + #这是一个增加学生就业信息的方法 + def add_s_w(db: Session,student_work_info: StudentWorkCreate ): + u1 = Work(**student_work_info.model_dump()) + db.add(u1) + db.commit() + print("已添加成功") + return u1 + #这是获取学生就业信息(包含学生姓名与学生编号)的方法(三个必填版) + @staticmethod + def get_s_w(db: Session,student_work_info: StudentWorkCreate1): + u2 =db.query(Work).filter(and_(Work.sid == student_work_info.sid, + Work.company_name==student_work_info.company_name, + Work.salary==student_work_info.salary)).first() + + print("信息查询成功") + return {"学生姓名":u2.student.name,"学生班级编号":u2.student.cid, + "学生offer下发时间":u2.offer_time,"学生就业时间":u2.open_time,"公司姓名":u2.company_name, + "月薪":u2.salary} + #这是修改学生就业信息的方法 + @staticmethod + def update_s_w(db:Session,student_work_info: StudentWorks): + i = db.query(Work).filter(Work.sid == student_work_info.sid).first() + if i is not None: + + if student_work_info.company_name!="0": + i.company_name = student_work_info.company_name + db.commit() + if float(student_work_info.salary)!=0: + i.salary = student_work_info.salary + db.commit() + if student_work_info.open_time!=date(1970,1,1): + i.work_time = student_work_info.open_time + db.commit() + if student_work_info.offer_time!=date(1970,1,1): + i.offer_time = student_work_info.offer_time + db.commit() + return {"message": f"{student_work_info.sid}号学生已经修改成功"} + + else: + raise HTTPException(status_code= 422,detail="输入学生学号错误") + + #这是删除学生信息的方法 + @staticmethod + def delete_s_w(db: Session,user_id:int=Field(...,ge=0,le=100000)): + u0 = db.query(Work).all() + for i in u0: + if i.sid == user_id: + u1 = db.query(Work).filter(Work.sid == i.sid).first() + u1.flag = 0 + return {"message":f"{user_id}号学生已经删除成功"} + else: + raise HTTPException(status_code=422,detail="输入的学生编号错误") + + + + + + + + + + + + + diff --git a/student_system_final/database.py b/student_system_final/database.py new file mode 100644 index 0000000..aa92263 --- /dev/null +++ b/student_system_final/database.py @@ -0,0 +1,34 @@ +# database.py +# 本文件负责配置数据库连接、创建引擎、会话工厂,并提供依赖注入函数 + +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker,declarative_base + +# 1. 配置 MySQL 数据库连接 URL +# 格式:mysql+pymysql://用户名:密码@主机:端口/数据库名?编码 +# 请将下面的 'root', '123456', 'localhost', '3306', 'student_system' 替换为你自己的实际信息 +SQLALCHEMY_DATABASE_URL = "mysql+pymysql://root:123456@localhost:3306/student_system" + +# 2. 创建数据库引擎 +# - pool_pre_ping=True 表示每次从连接池取出连接前先 ping 一下,防止使用已断开的连接 +engine = create_engine( + SQLALCHEMY_DATABASE_URL, + pool_size=10, +) +# 3. 创建会话工厂 +SessionLocal = sessionmaker(bind=engine) + +# 4. 创建声明式基类,所有模型类都继承自它 +Base = declarative_base() + +# 5. 依赖注入函数:用于 FastAPI 路由中获取数据库会话 +def get_db(): + """ + 每次请求创建一个数据库会话,请求结束后关闭。 + 这个函数会作为 Depends 的参数注入到路由中。 + """ + db = SessionLocal() # 创建一个会话实例 + try: + yield db # 将会话交给路由函数使用 + finally: + db.close() # 无论是否发生异常,最后都会关闭会话,释放连接 \ No newline at end of file diff --git a/student_system_final/main.py b/student_system_final/main.py new file mode 100644 index 0000000..5926d25 --- /dev/null +++ b/student_system_final/main.py @@ -0,0 +1,43 @@ +# main.py +# 项目入口文件:创建 FastAPI 应用、注册路由、创建数据库表 +from fastapi import FastAPI +from fastapi.middleware.cors import CORSMiddleware +from api1.students import router as students_router +from api1.scores import router as scores_router +from api1.work import router as work_router +from api1.classes import router as classes_router +from api1.teacher import router as teacher_router +from api1.statistic import router as statistic_router +# 2. 创建 FastAPI 实例 +app = FastAPI( + title="沃林学生管理系统", + description="学生信息以及就业信息的增删改查", + version="1.0.0" +) +# 3. 添加跨域中间件(允许前端跨域请求) +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], # 允许所有来源,生产环境应指定具体域名 + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) +app.include_router(students_router, prefix="/api/students", tags=["学生管理"]) +app.include_router(scores_router, prefix="/api/scores", tags=["成绩管理"]) +app.include_router(work_router, prefix="/api/works", tags=["就业管理"]) +app.include_router(classes_router, prefix="/api/classes", tags=["班级管理"]) +app.include_router(teacher_router, prefix="/api/teachers", tags=["老师管理"]) +app.include_router(statistic_router, prefix="/api/statistic", tags=["统计分析"]) +# 5. 根路径 +@app.get("/") +async def root(): + return {"message": "学生管理系统!请访问 /docs 查看 API 文档。"} +# 6. 如果直接运行此文件,启动 uvicorn 服务器 +if __name__ == "__main__": + import uvicorn + uvicorn.run( + "main:app", # 指定应用位置(模块名:应用变量名) + host="127.0.0.1", # 监听所有网络接口 + port=8001, # 端口 + reload=True # 开发模式,代码变动自动重启 + ) \ No newline at end of file diff --git a/student_system_final/model/__init__.py b/student_system_final/model/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/student_system_final/model/__pycache__/__init__.cpython-310.pyc b/student_system_final/model/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8855a24c1c291cd65c62851250b8396b470965c6 GIT binary patch literal 167 zcmd1j<>g`kf@xdhvq1D?5P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;!?dkn3U95G-;9oStnV}*~uNTcQ3YA;_4u}NEGxD z4Tu67%KQ_z2%XZ=&@RK&C1qS?`B(pmLJ;ek6ygAO%J*5s!KD4)H|f=OHP1 zdVuQe8mgl@amh|AJJq=KRb$18&@MT!dfJ@0Y?oPaI90;Md$MKLMLtktS7;%bowkjc zOlN?j7tHv0IhM>AY6TllgdY3)w^s~c8@8E&5r|-pNWd`(MI>S#@bDra3HT|G&ar0< zI0HOb`T2jjVgFyuQ=VOfq!1+^h>GWY2xtvZ0e%TJ)_Dbb*Ic~g>5ETkPOZzgy)PWlqF>V_U zm0Wei#;0`F&N}FnFfKh(HchdU>rDq+Jt4v9$^&FN^ z!?YkBdLH3;%C#R9moJ;{Pw2D{7|XP!79NfaCxY?Sd${OWvJ;*88h!vtwn_lIRZG4i zecz|O`LhRR_u1&t(Pa7sj zAV$d1sxOL)B`w3%AUvON@cIPzv)Kf(t7}hUADD+g6ICVjqlGxQ~<{UZ-jpV Do~{2g literal 0 HcmV?d00001 diff --git a/student_system_final/model/__pycache__/student.cpython-310.pyc b/student_system_final/model/__pycache__/student.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cf4dbe35d74ee420192757c6df7804fdbeb7038a GIT binary patch literal 1123 zcmZ8h&1)1f6rarZe$4j6`g!mmRoF|>o@-CK+VCR=f!w zycaKu2fcXgf0C=nQt;r#yDzib51Juwf4{u9FY|scnKDV54vatI>)xHvaei5Hari(s zV5*m3s6!EV1j0zT*cBf3gpYj@;6Q{p6cLV)jd6J_8n{tok2ggNw~+J9p*{`XIW%Cc zLl3uU*mt_o31o#I6KL_$s?bTNKeYi zjw@&lQ`mo1%6%Mc+Em-!TP9A^f(VwTrkSRqq!qWgou&sB;d4)trrPc_qtb;9q}|1M zDyK585xkYOht&8s%0z@x$&|vO%0^|$O(4i#DP?3sno1L?Q*Dn^%nCX~4MwZ1K0Y|f z;0#q>i#wedu@AeAjp zt%8XiA9c_&TAV*^)CM%07F$&RW4oI`xd)u^Y{bOmT)SE z^e38=D4?Odf8rLQ=zah_<4r`)md7)m(fGZYDYGm=u#(y3`+<+pZ)e8<&_IVY)Dexa^Lr}RgpyA8RZk~0>GVMLbxKo=ULg^R=o1o=OjbV4 zL_9%5at+zhFtX9hQZ>4;@#~_N3u$aLsZCxiEIHt{Jj%7S;aHWtw#m3OGG7#LWIMz* zHB#|9FN^9VUxFRH;FW|sp45$yMLl=|uGeK;L2i6|C`dID2l1~L>LZ2#P+k+Wnh zf)#eC;f1)D6{bD76S(_bd@RVhM^l-Jo=8L=^npl$S7yV>9B|UC+TdW7GmnOz?JrHP zxoO#{Y;DGyy3C8Yks82$>~Et-RW8QBf)tHXe5T|z2FQ+IJ{*EV+GfeF`F=^OVKE&r;MF7Tx~rWW3|h^F^vZ~4a@?fq)W_lVPf}> z4{$7zAGl^kqfO-EZaYVCtoXtZr^Z|8-;ufJ{7(FR3*zAE^x>1okCttHQWn!cKQ7l_ zFV;W5t-pL;|GHXVT}=O1sI6+L*>PTQH3h^{?Od*Sqh)LQkgx}*+5976xX-3T1j>`ZjU8Bv~&+KNlvAd5|ZFj3cX}c!-AOXJg=3^NSl##*qm$} ziU};q!GYuu($dmUiqk?rFzkOa*JgLUe?YILZ{#&Lbi_R7_j@0DA2UT9hX$?};?4a( zY{U3lgNsXRZ{jW=qhJOzxgktq3X536Cbn>hBV6JNk9fi-z6eNQYCDU!L`cHsZ1c8= zNMst|GY6vkF__E+3j*fto6Kjy#6hOjFyR@q?~vq6gSA=o*kBPv`!-o)@m-^vEHM+K z8z}E~!E2E#|Es)$AxP!jtz?!DRd9z^(8~lUcZ(OaQjR8++oSh5sBo*0kPY*%Vca!U zB!SZ^EAnzD8zFXX(GpZV;Iu5$3g}=51KWd)J-Sp@HG{lL8{H;SJ+yC+WG1K_rw?GP z!j(gc=AG4f^PC&##4j!n!A;!dBNSi|lNrQfCb7W*ms$AP%$YdEL+mpbTjMc*Vv(T1 z0pb=55w{xLMjSObZ2V)Eu(gRz+6`J~ml_m7%sP;;%WMO6YwSI2>HEs>txEM*>GtXX zb2{1Gn;joytZT~zp^9l;6znVsnH~Jn zHRWXl%MDFOC{Fec7r##zhku^@`bwIb{Sd|c`ET>d+r^W==DT}Wu3ud|J$iRMeK(z6 zxpsB_{3WK+wUp0bo7TKK4cNGT@PF6&(GRoZWAvLHe7Ai0qjGQSiK<{#UWtKPB@Bw3 z;qX*)j}9KBqheI!Wq|UV?z#%nG^Ya6RE23O3RZJ{j?(mDP5DX_r)j0DJ%!T3G$cME zL#}DzpdiuN__dAlhLAIm#2xJvIglhP(;c8}Wuu&JPKQ!IIjMVu{nbfB`LiKE(xevu zY@xXGS^wInH?EJy6~^h$j(%DkzFxfje(~&E-PGyp{@GnE$7KZ~-Oh5#`&b3={_1C& zqp@7aP%YeL2Ss2w=KAVO%*5=Njb8U6EFW^p@hOP$g(7u*QqNiHIZIy)eQBf)sgiS_ z%|eQ%Ditt_4Z{~E+u9}&P*F`aWda(=K(^pBRxDnSs^8G@XAp Goc{o9k7}I& literal 0 HcmV?d00001 diff --git a/student_system_final/model/__pycache__/work.cpython-310.pyc b/student_system_final/model/__pycache__/work.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..28c5fd990a30a4fd3245cef65a2c8573541e55de GIT binary patch literal 1110 zcmYjQON-n_5Y}rXjYgwgKYl`p8G`re=VFYpje|*8h}Xf;3^eWOni+Y!)!LSX(Ok#m z7RVuY6CWIMNG>`0pY%0^VSYgFuGXxx+Zxq;RVsDW_jO4Phlzvh@vGn8eDEFTAM0FR zJ#-%7T@`4!!(HJ>m$=d+p7eB*3UG9r;{b3Dw6N!(#y^kqU4!~q#V3%nPlJpCq zx9C|WL)O$PFHkXwJk6lgxn#Pfr_e42=gB)&&XHl*6!}>Li)8=)-MyQ8`}o6X#9_)B zQLhh>;o6SY+Ox(*W1^FdekQQ>FgttACa1JiWrGI-)$!<>i773Z1WHXpsZ_iX7N?Y+ zHB6j88B$ua*8(=KwgoiKu7euLQmEGUPIInfThzyPwH4m%cxs zCrXyAXuIM%vZ1hI0=b)DD%eb0DkeIY;15TCjeckTdxGfc(RlCP!G77+b5)H0{qy7M z*Y~Txep~(W)9UX}t55I8UxeOF4xQ!&6Jw+YVr;e8DO`v3(O!2y1I;fo_W%F@ literal 0 HcmV?d00001 diff --git a/student_system_final/model/classes.py b/student_system_final/model/classes.py new file mode 100644 index 0000000..998d27e --- /dev/null +++ b/student_system_final/model/classes.py @@ -0,0 +1,15 @@ +from sqlalchemy import Column, Integer, String, DateTime, Float, Date +from sqlalchemy.orm import relationship +from database import Base +from model.teacher import class_teacher + + +class Class(Base): + __tablename__ = "student_class" + cid = Column(Integer, primary_key=True) + class_name=Column(String(20),nullable=False) + start_time=Column(Date,nullable=False) + headteacher=Column(String(20),nullable=False) + flag=Column(Integer,nullable=False,default=1) + teachers=relationship("Teacher",secondary=class_teacher,back_populates="classes") + student = relationship("Student", back_populates="classes") \ No newline at end of file diff --git a/student_system_final/model/student.py b/student_system_final/model/student.py new file mode 100644 index 0000000..61a502f --- /dev/null +++ b/student_system_final/model/student.py @@ -0,0 +1,23 @@ +from sqlalchemy import Column, Integer, String, DateTime, Float, Date, ForeignKey +from sqlalchemy.orm import relationship +from database import Base +class Student(Base): + __tablename__ = "student" + sid=Column(Integer,primary_key=True,autoincrement=True) + cid =Column(Integer, ForeignKey("student_class.cid"),nullable=False)#班级编号,外键关联班级表 + name=Column(String(30),nullable=False)#学生姓名,字符串形式,不能为空值(必填) + address=Column(String(50),nullable=False)#籍贯,字符串形式,不能为空值(必填) + school=Column(String(50),nullable=False)#毕业院校,字符串形式,不能为空值(必填) + major=Column(String(50),nullable=False)#专业,字符串形式,不能为空值(必填) + start_time=Column(Date,nullable=False)#入学时间,字符串形式,不能为空值(必填) + end_time=Column(Date,nullable=True)#毕业时间,字符串形式,可以为空值(未毕业学生) + education=Column(String(20),nullable=False)#学历 ,字符串形式,不能为空值(必填) + consultant_id=Column(Integer,nullable=False)#顾问编号,整数 + gender=Column(String(3),nullable=False)#性别,字符串 + age=Column(Integer,nullable=False)#年龄 + flag=Column(Integer,nullable=False)#逻辑删除,当值为1是保留,当值为0时删除 + score=relationship("Score",back_populates="student") + work=relationship("Work",back_populates="student") + classes=relationship("Class",back_populates="student") + + diff --git a/student_system_final/model/student_score.py b/student_system_final/model/student_score.py new file mode 100644 index 0000000..0f2d87e --- /dev/null +++ b/student_system_final/model/student_score.py @@ -0,0 +1,18 @@ +# model/users.py +# 本文件定义 User 表的结构,映射到 MySQL 数据库 + +from sqlalchemy import Column, Integer, String, DateTime, Float, ForeignKey +from sqlalchemy.orm import relationship +from database import Base +from model.student import Student +#建立学生考核表模型 +class Score(Base): + __tablename__ = "student_score" # 表名 + # 字段定义 + score_id = Column(Integer, primary_key=True,autoincrement=True) # 主键,自增,索引 + sid = Column(Integer,ForeignKey("student.sid"),nullable=False) # 用户名,唯一,非空 + exam_num=Column(Integer)#考核次数 + score=Column(Float)#分数 + flag=Column(Integer,default=1)#状态 + #一对多 成绩表 + student=relationship("Student", back_populates="score") diff --git a/student_system_final/model/teacher.py b/student_system_final/model/teacher.py new file mode 100644 index 0000000..2984907 --- /dev/null +++ b/student_system_final/model/teacher.py @@ -0,0 +1,17 @@ +from sqlalchemy import Column, Integer, String, DateTime, Float, Date, Table, ForeignKey +from sqlalchemy.orm import relationship +from database import Base + +class_teacher=Table("class_teacher",Base.metadata, + Column("cid",Integer,ForeignKey("student_class.cid"),primary_key=True), + Column("teacher_id",Integer,ForeignKey("teacher.teacher_id"),primary_key=True)) + +class Teacher(Base): + __tablename__="teacher" + teacher_id=Column(Integer,primary_key=True,autoincrement=True,comment="老师id") + teacher_name=Column(String(50),nullable=False) + gender=Column(String(5),comment="性别") + phone=Column(String(20),comment="联系电话") + is_headteacher=Column(Integer,default=0,comment="数据状态 1-班主任 0-教师") + flag=Column(Integer,default=1,comment="数据状态 1-正常 0-删除") + classes=relationship("Class",secondary=class_teacher,back_populates="teachers") \ No newline at end of file diff --git a/student_system_final/model/work.py b/student_system_final/model/work.py new file mode 100644 index 0000000..6e33388 --- /dev/null +++ b/student_system_final/model/work.py @@ -0,0 +1,17 @@ +from sqlalchemy import Column, Integer, String, Date, Float, Numeric, ForeignKey +from sqlalchemy import create_engine +from sqlalchemy.orm import relationship +SQ_URL = "mysql+pymysql://root:123456@localhost:3306/student_system" +engine = create_engine(SQ_URL,pool_size=5,echo=True) +from database import Base +class Work(Base): + __tablename__ = 'student_work' + # 包含字段:学生编号ID、学生姓名、学生班级、就业开放时间、offer下发时间、就业公司名称、就业薪资 + employment_id = Column(Integer, autoincrement=True,primary_key=True) + sid = Column(Integer,ForeignKey("student.sid"), unique=True) + open_time = Column(Date, default="1970-01-01") + offer_time = Column(Date, default="1970-01-01") + company_name = Column(String(50)) + salary = Column(Numeric(10,2)) + flag = Column(Integer, default=1) + student = relationship("Student", back_populates="work") \ No newline at end of file diff --git a/student_system_final/scheme/__init__.py b/student_system_final/scheme/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/student_system_final/scheme/__pycache__/__init__.cpython-310.pyc b/student_system_final/scheme/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..62379f1744a92eda66c8dc3f2f1dcaad0b6f5ea9 GIT binary patch literal 168 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.offer_time: + raise HTTPException(status_code=422,detail="就业时间必须大于offer下发时间") + return self +class StudentWorkCreate1(BaseModel): + sid :int = Field(...,ge=0,le=10000,description="输入0-10000之间的学生编号") + company_name: str = Field(..., max_length=50, description="公司名字") + salary: float = Field(..., ge=0.1, le=1000000.0, description="月薪") +class StudentWorks(BaseModel): + sid: int = Field(...,ge=0,le=10000,description="输入0-10000之间的你想修改的学生编号") + # s_name:str =Field(...,max_length=50,description="学生姓名") + # s_class : int = Field(...,ge = 1,le = 100,description="学生班级编号") + open_time: date = Field(description="输入你修改后的时间,要写如下格式YYYY-MM-DD, ",default=date(1970,1,1)) + offer_time: date = Field( description="输入你修改后的时间,要写如下格式YYYY-MM-DD ",default=date(1970,1,1)) + company_name: str = Field( max_length=50, description="输入你修改后的公司名字",default="0") + salary: float|int = Field( ge=0.1, le=100000.0, description="输入你修改后的月薪",default=0) + + @model_validator(mode="after") + def time_available(self): + if self.open_time > self.offer_time: + raise HTTPException(status_code=422, detail="就业时间必须大于offer下发时间") + return self +# 允许 Pydantic 读取 SQLAlchemy ORM 对象 +model_config = ConfigDict(from_attributes=True) + + + + + + + +