From 92391cfcd17feb55f4fece183bd24ea4bd9ea61f Mon Sep 17 00:00:00 2001
From: suzxzd <474390146@qq.com>
Date: Wed, 26 Jun 2024 10:12:13 +0800
Subject: [PATCH] final edition

---
 .idea/codeStyles/codeStyleConfig.xml          |   5 +
 main/__pycache__/mysql.cpython-310.pyc        | Bin 7703 -> 7792 bytes
 main/__pycache__/mysql.cpython-311.pyc        | Bin 14300 -> 14300 bytes
 main/client/Client.py                         |   2 +-
 main/mysql.py                                 |   2 +-
 main/server/Server.py                         |  17 ++-
 .../mqtt/__pycache__/forms.cpython-310.pyc    | Bin 525 -> 973 bytes
 .../mqtt/__pycache__/views.cpython-310.pyc    | Bin 2832 -> 3879 bytes
 su/myproject/mqtt/client/Client.py            |  15 +-
 .../client/__pycache__/Client.cpython-310.pyc | Bin 8802 -> 9110 bytes
 su/myproject/mqtt/forms.py                    |   8 +-
 su/myproject/mqtt/views.py                    |  40 +++++-
 .../__pycache__/urls.cpython-310.pyc          | Bin 1180 -> 1282 bytes
 su/myproject/myproject/urls.py                |   2 +
 su/myproject/templates/chat.html              | 108 ++++++++++++---
 su/myproject/templates/forgetpassword.html    | 131 ++++++++++++++++++
 su/myproject/templates/login.html             |  71 +++++++---
 17 files changed, 355 insertions(+), 46 deletions(-)
 create mode 100644 .idea/codeStyles/codeStyleConfig.xml
 create mode 100644 su/myproject/templates/forgetpassword.html

diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 0000000..a55e7a1
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+<component name="ProjectCodeStyleConfiguration">
+  <state>
+    <option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
+  </state>
+</component>
\ No newline at end of file
diff --git a/main/__pycache__/mysql.cpython-310.pyc b/main/__pycache__/mysql.cpython-310.pyc
index 56750767a9311603238435799e80e8a9271af505..4c741441bf8adf48c8fb66195eb36832abec5fdf 100644
GIT binary patch
delta 2010
zcmZ8iOKenC7{2Ge=FaQR4D;$!+Xe|kp_Yd&p#_SCVhdDaDb<N|y!4(vXgeLwy|rmG
zjSGzn5)#S3z(f<vPFxsG6Wy>7bwT1|Z7wb}af5N8!JQ=f|7WHYnVbK+Xa4v3&;Or$
zv;WV2dnq1|DENEh4}Ut<dc$sEna?|;%;K?)>@9^Un>}nmV<+J+BMsN|hCUv5Rad*t
ziuP&6)m`Hq#WmhmiwV~pQwpIVJUHw4=ayW)aGM1omrpy(3%<x>0MP*F&35=*?@c{N
zf3pM`gwaA04j7BcXK)=vJYIIW7<Cpoe5E!uv?23ZB+o{$6qC_ovk3fX1gr~go2!j`
zQBpv9Nc$j_7>lqSs@RM1GEm7|FcCW1ZK7}x$)hm7vcYI`_*Q+**L}k`XY^Z)DXuc6
z+-9SN5PTilt&?jwk;}u~TqYBkQ-V7_KR{k|1WV09&gx-(a5vkK?M2Rhq=yvAQdG=R
z^un6;QK}Cap5&@KRGo=I*b_d~aSXWyO$^{G2u;oMsrkx^I6+KRyofImfmCC<#g?K{
z#qqqACE>~~s3^t_o~my!y!m~2p0N=)9Od!DH4mhR3ZF!K*f{(e{g@5HwOCWj8Dfu+
ziY}<Ef@&6Ml@(W<rEuYp<GSM>7q7$5vGtbYq-lsD(mc1NE|Wyx%kd#L4R_-G+5X4!
zQChu1Fh)f&$Z{C=*v)KcD_NMb&tI${f32-{4C~5_vd*f?N##;zU9GBDh%_V}$v`q)
z_Mx$^RoO<Us?i}`4OiI&9+a;5)@m<P)^(<=Mg1@siH;USv{HQ8W4mZYy&?7>6e4ge
z(Vmg(z;r4VY&B7<2$U0hnXCYOnuwbMwY?6wn@F2FGyjQ&;HShcxR;N?OeWq<^;?Vk
z$`wqy%Brf%u4@}A_0xpnsxmEYbtk5!$+UEsh;<BTPh>>NTo}T_w&6m&OmLpy$<x`+
zpR{YI1D_?W*t_`GOCqRh2EI)mipuIwkkYGE^TrFfTq30i0yd%+VQLzi@q#>oM_DT;
zI#E)v1hu!=N6>`;!{%;PJP+@s+Eecnb9+L?e)1fV<3N%ZHh)Vw?CdzL+Yka{WtIyr
zWWA~UMGJeCi_+y)S^lE#a&Iayrsss`*Bb94*-|9~ZGo4?8Mu+|Oua^?;brW<lI!?R
zeb>LFcd!rOVS1ePz;Nc)^dT~32skMR$%9qDXS@f*6{ksL%H0*?Gu$sNiBfHJ1(^oA
z=e)`PS8Vbkx=9wQDb~lqjxEg1^U@;sJZFY~30JcttRL=V+oNBQ#ZiLEdRb33i6i78
z<?*RyG3T$At}b)WpIa)6E?CTsgj|%4ie@<%bno4R`?)rD03PK|H<INyNcA&|;Uy>U
zup{Jrvyx{l%26z)31*<$&^!4OE#(Z$Stk#*R+8;6`)QbXRAaf>f*I6GTgJ<^?ule!
zgkpTw@n*SOa?0Kc7qajL_QPghV-sV?;bK$gTUSu6kPtaC*^Vv4%G6}o0g|31pqot0
z5X>S3w%{I~#MU(?o=#27Z|MiIGGEzNr0fKiPTQJ+Tyvh?hpy(oFU_H7NXWdxPv<3T
z5+PfM;Hhv%EnJyI6rh->Z~t+AXW@pKHWpF#0B*KSCgqSVkUou;Sfo?zpq+h(RR1`s
zDo$FQ2&au?g&Z7j?O+3Nx%J>dIc)Ti5VgCRRzn0dui_HHB!R3bSqu8E<RNHHbdzmN
lu^2rW1H0qjq?t65(PYH7tcYdVroAh<6W`6rxNXJu{RarKsS^MI

delta 1964
zcmZ8iU2GIp6rMAGJNw_=?sh5Nw%hU(mTfBtl!&E*ErnKSfP#%RZ5=ze-9o#&+?leL
zbcF=s8!_Z28WR)Y4PtyS#YbZ_#GjCu_+X;rvoXAh)x-x)Jm>C0BRe_Y+&Mq@o_qfG
z_ks5ZV&!Nwq~Pztua)`b?5$W9BA*t*us#S!G&m%#>V@6M6-RZn8;YY{SEr(mKB43d
zKR8shy;Eg}E!_h@;IMgnWyup|tyO?Akl2np@-#sTVLTrb<Hj<iM3=FpC5N0&BsYR!
zDJIYp6aN}M^opO%)z$*?cOh+%W26v)5F}Mz5VoEb?*tC_87LS+a<d4YavSa_KyTI4
zJl!)Ev^xNbqf99GU_5V%jleD_;Mtj!Z_aUMdu%Tm>j;*b5;Immyg;s{`;oH;X~QIu
zqCyOKzxc}fC~*iGuH>poRR?}l@ZkRL0p#X2K8P<rFjr)A7b{i%5;0YN1YbNP9><%-
zFTr^9W&Cti1iZ))UZj0J6}kv8Dz1fD^dR!l<S3a8i9f>qa8BeScMnQN3vzvPvE(xD
z`2qG8n_KZ1A0^!rWT$hACZ}NeTBYjnF#(B`WjoG!G<jWYkJhq>NzvfLr1;7cZRshV
z_jz;#n9ySbX}V=yev($F3C>Vty2z4FbCU=ZnGmQUBoir!Q5vQziH~Ea&n}_Dm5zE+
zYRZCAgEeJXnNHT!HT43KhNL4I4t%KBv^BVGuE~U53a-H<CQVno!0G`|YC0%a!k#70
z#Je*(Z^w=K4uYKod4zmWyc_R|`=(u~u#(dVig*z3fiaAHuKf}!xj6(?wLq7o13l(H
z5mW4G+If{y^5m!Cg2E_Ei*9=*;wcx<|21&nrg~eYGMmJ1kUnaw+t5c<`iS?rjwLs#
zyoP00Q{TpZnP{x4P{kaLV|t(Zer^PFk;DD@DT(8>+)SvpsVQ^W7P)~6ZWDs4CdIDA
z{;*8cc`|#I($jhtmnBlFw~VS`T9TNSvzV5Yc%#K?=DSgxw>UKy?;+?F-z0kUK3s}U
zqa*Pi@itqQ@1c!Dq<)Je``1q-Z8$kW>l}h_REvzWdM+q6zE$Q9<FjwB%GCI}!`wOF
zm|x_sSFg}>WJ_W7wIx>KqvEgTLShoXr-Cb3sk4sl*?8f-sU7fvm`t6A1LBj^o%wxa
z1_&6!=gHb?OdIzRarrS4net*&(FNwsmicVG%Q>0)x@%wlf4|T!{5g^Z>Wb7ekK-xv
zZ8`#<i67HrIQeodUE%wr_#(kfBap{Lr<F<j2^YJNFM6x9msXhTEtX3d&M#WVbcV{J
z!{~&sMQ<htd&PL>c&mfVFOeGAiQv4G1I>|5^Dy&wc%IH!ASjCOw;Y@qp`~nVIRa<{
zeu_XgfvlI~^hwc_m6JF9dJs$YGHdKavLM1#v}n6U=FHk9x5~J@YqPlA+5!*PZ?<j)
zI4tgNEnK~bs`)slal<#ymq$zY<k2+hIL)&9@F>!15y6jf=3?wCw(C~05csq1aheO9
z^!-SQRW}vMLylq7l!jx)wha6%uC@I+eE~%yT>2G!)-M?ss&;M@Jae2;Kdww78G?8t
z1W)}N6F+2|4eFWS#G~v?lkBKv(ytJdsQSC<X5S&XF$A1?Dz;UW2wRI}`Lwvz-VKA|
ze*3;Y*;(`t(wO748YZCT<kJK*1TvzFxPPX}w+5EW&dL%S1eCbD#nFx}>0r#VLY5UX
PV>_F+;k&IVnza4{ES!_)

diff --git a/main/__pycache__/mysql.cpython-311.pyc b/main/__pycache__/mysql.cpython-311.pyc
index b66d6daa0993c2dd2fbf4f978ea88af4194c4e0c..875b0080eb31d7b14a15ccb38c291fab9ac226e3 100644
GIT binary patch
delta 22
ccmcbUe<z=JIWI340}v#<DM=ID$a~%#09gwMY5)KL

delta 22
ccmcbUe<z=JIWI340}#wDFG>^I$a~%#09StpF#rGn

diff --git a/main/client/Client.py b/main/client/Client.py
index d06561f..1614898 100644
--- a/main/client/Client.py
+++ b/main/client/Client.py
@@ -305,7 +305,7 @@ def reset_password(self, answer, new_password):
 
 ####################################################################
 def main():
-    SendMessage("1234","1234")
+    SecurityQuestion(userName="2222",question='1',answer='1',new_password='1234')
 
 
 
diff --git a/main/mysql.py b/main/mysql.py
index 3bead31..251a27c 100644
--- a/main/mysql.py
+++ b/main/mysql.py
@@ -217,7 +217,7 @@ def set_security_question(user_name, question, answer):
             return False
 
     @staticmethod
-    def verify_security_answer(user_name, answer, new_password):
+    def verify_security_answer(user_name,answer, new_password):
         try:
             user = UserModel.get(UserModel.name == user_name)
             security_question = SecurityQuestionModel.get(SecurityQuestionModel.user_id == user.id)
diff --git a/main/server/Server.py b/main/server/Server.py
index 6a05722..b39b420 100644
--- a/main/server/Server.py
+++ b/main/server/Server.py
@@ -195,8 +195,10 @@ def on_message(self, client, userdata, msg):
             success = SecurityQuestionManage.set_security_question(user_name, question, answer)
             if success == True:
                 code = 1
+                print("密保保存成功")
             else:
                 code = 0
+                print("密保保存失败")
             data = {
                 'action': 'set_question',
                 'code': code
@@ -218,11 +220,17 @@ def on_message(self, client, userdata, msg):
         elif msg.topic == 'verify_security_answer':
             user_name = data.get('userName')
             answer = data.get('answer')
-            newPassword = data.get('new_password')
+            newPassword = data.get('newPassword')
             returnTopic = data.get('returnTopic')
-            success = SecurityQuestionManage.verify_security_answer(user_name, answer, newPassword)
-            if success: code = 1
-            else: code = 0
+
+            print(user_name,"密码"+newPassword)
+            success = SecurityQuestionManage.verify_security_answer(user_name,answer, newPassword)
+            if success:
+                code = 1
+                print("密保验证成功")
+            else:
+                code = 0
+                print("密保验证失败")
             data = {
                 'action': 'verify_security_answer',
                 'code': code
@@ -297,5 +305,6 @@ def main():
     c=Like()      #进程3,处理点赞
     d=ChatAll()   #进程4,处理所有消息
     e=ChatSave()  #进程5,处理消息保存
+    f=SecurityServer()
 
 main()
\ No newline at end of file
diff --git a/su/myproject/mqtt/__pycache__/forms.cpython-310.pyc b/su/myproject/mqtt/__pycache__/forms.cpython-310.pyc
index 4b8882b14738e14a46d0242fbead4bf96698c8d2..8a54ae5cb390017678fc75e975a77160e668f4fd 100644
GIT binary patch
delta 520
zcmZ9IKTE?v6u@)&pEfCyK^!_b2|@h=PMs8&BG@T|5PD~AsY$)0)In&)qFn-(78OBI
z2XV3D<RpFqzd*pvHs(|4y$lk(aKCWxckkZ23&jtm;2B1aW20vWyDP%5P(-ES^6J6{
zhea&)IV=&>;7<fw#PT+0DK9%U)U857cF1f|V$(ljAe@abXY)j8h!|n`OIW~S9bqX%
zSPlhSPMz}S)QnU9IW6PV)OB-dqQ(x*XJiiRtV1I**F9Pz!ItCu9gkwR+D|T6UzI4|
zYC2W2=QS~*ZH<NE@#AdpIz1096iH4HP~Q@$!~|6UaINHrp{+AapHIKuZ<5PNH@Uyc
zMB=CM>~4_sV4unG{cxO|h4I@YzV5S}`1ZJL<*CXHg_;zeoAQ7>L!?#6VX*18+5v?s
zk$TW3eo*(^NOoMmLnt+1ZviluViY4|jY26n$_J=i5y7{J(s<dDA{jRvx8|jlA`xDJ
U3XpD&KGBj6?dY7&oBX`=3tm`;sQ>@~

delta 61
zcmX@h-pj(5&&$ij00gzq3etEOC-TWK>P^(vWlLcRX3%8aSdh-h?5D{xxsh3N@_c3`
OE;gV_9tIvJF(v?_7YpA2

diff --git a/su/myproject/mqtt/__pycache__/views.cpython-310.pyc b/su/myproject/mqtt/__pycache__/views.cpython-310.pyc
index f92c3c8136e27a3acab51e87cb88ee8ead18a227..f434946426562548f2b7a055b2a4e1f37d2d2faf 100644
GIT binary patch
delta 1127
zcmY*X&rcIU6yBM3x7+P@t^6kPLkO3uF;P%d5ET;iqS0`Ym}q4dq|g>;ry-hc8pS9v
zkU$oVCKyX%0(zkF#0B;L*pml=axlht(v$D)wh(r+-@Ny|>GaL}zJ<Eg79$glY7#uH
zKgB4iUNoA>+T!uKwi;IZOd76cGOL?ZQ#HdiL}K-<0k~R5hNO7o=gs>nah=w1XX8ie
zDwarytmTGMre!6@Ox^`Y{&Ob6CrGFBCVY={Ie)_gq}RDdoAXbhW=lzlkqOFs1SwF+
z0xKj(Y*Gj^3K8`p<N`uYD!HHtu^>kE(hMPz2-&o}2E0|pnoaEhljj3a4;M71tl-WF
z3o(_2mtp@9W*W;!#t9~I{RXdrR$TRA*0jWUChaPTv^8yVeg^0`<riV$eF(=8&H`ks
z0Je(He|&paTK~H9Wqo^gVe934ei}D)BAfz<>%0l$ZiI6P=MgR-wC53ZgjN7IHe`-u
z`M7v=tK0=YinTTb3J{lh2gW@J`yF`)7|3~W2qHIPnWA!+Ng%8S0FCHGgI6I2QQ?i<
zfy4lkUxsR&xK)E0K4yxW3Co(!a0Xdwgg~kCgdkAh8-UOH0I;XsRY4$z$$H8KRwO>?
zq=GGZn<RrwZj^GekWmynXv<8Q59So16hbV7!q`eu<-I7BEirY4dQycwk$g@oa}ngy
z0YPS@91%L~)>+ghpkV+sG<*$tE%a5H4h)#rK^_nKW8NFuu%0%j?@pC3>WNy>bEoiR
z_r?6ao{jMPEDFA}w6;CFv9&P2J^R|%eRt_?saS+`d-;>^0iXZ1Iaexfz$w>D#aFH|
z>P@xsXOF87<|iMB)FeNGT}FMcT!Gm0BX7p21>q8a^Ih)9hkOs<{sUKq6mRMh%eTRv
z7kEF=Hhfk)0P3%LF2E>8(G5B<I#mh%qa2P=Z-2bb^PU@F$wYcA13ii<&x6iw?K<gp
sR<-t6FC6DNhkFh8JI%B{=BmA^49iZMeP|r3-TAFGt7=3wbVH~A0rm<Pga7~l

delta 150
zcmZ23H$jXqpO=@50SG=+7o~ObPUMqe?3t+D!^#-UpeeHPMiK{O)MRT;V@XY>TWrN8
zi6y1Qx7c%2i;EM}Q;Up%+NvhEbLub}PTs<qzy{(M@l1ZeCo)-&ON-4C$kh~{?82AA
tXfk;vpAw_x<lB5|3Nk=p4h9}Z0Y)Am<N!iGW;Rw1W)4XXc@9n<ZUCgBAm;!8

diff --git a/su/myproject/mqtt/client/Client.py b/su/myproject/mqtt/client/Client.py
index 50f590a..4613a96 100644
--- a/su/myproject/mqtt/client/Client.py
+++ b/su/myproject/mqtt/client/Client.py
@@ -159,6 +159,7 @@ def on_message(self, client, userdata, msg):  # 接受数据
         messages = eval(msg.payload.decode('utf-8'))
         # 读取数据
         self.messages=messages #返回一个字典的列表,['id':id,'senderID':senderID,'message':message]存到类中
+        print(messages)
 
 
     def publishGetAllMessage(self):
@@ -241,6 +242,10 @@ def __init__(self, userName, question=None, answer=None, new_password=None):
         self.question = question
         self.answer = answer
         self.clientStart()
+        self.rightQuestion=None
+        self.request_security_question()
+        time.sleep(1)
+        self.flag=False
         if userName and question and answer and new_password:
             self.reset_password(answer,new_password)
         elif userName and question and answer:
@@ -262,9 +267,14 @@ def on_message(self, client, userdata, msg):
         if data.get('action') == 'set_question':
             print(data.get('code'))
         elif data.get('action') == 'request_question':
+            self.rightQuestion=data.get('question')
             print(f"Security Question: {data.get('question')}")
         elif data.get('action') == 'verify_security_answer':
-            print(data.get('code'))
+           if data.get('code')==1:
+               self.flag=True
+               print(f"密保验证成功,密码重制成功")
+           else:
+               print(f"密保验证失败")
         return data
 
     def set_security_question(self):
@@ -290,6 +300,9 @@ def request_security_question(self):
         print(f'发布信息到 request_security_question 成功')
 
     def reset_password(self, answer, new_password):
+        if self.rightQuestion!=self.question:
+            print("密保问题错误")
+            return
         returnTopic = self.userName + "security"
         data = {
             'action': 'reset_password',
diff --git a/su/myproject/mqtt/client/__pycache__/Client.cpython-310.pyc b/su/myproject/mqtt/client/__pycache__/Client.cpython-310.pyc
index b36e243cb1f219a48d646a4deb4865cefef79c85..24135d9816feefeecb85a1c8829e40f2223759d3 100644
GIT binary patch
delta 1081
zcmZ8gPfQeN6#w4**%_AEad3g%?k=!EH5oN<FbxC}dNJ5mLnIih#uop~ii`5cZ)ZX1
z5JE|SXqz^9rmcxhXB+In!&0Krlfhn_rrtbIFA%q7V~n0`^rG(@Br(q9y?KAXdB5Mh
zS>N}=esd%e2{XD*#`9-a>}7Mn>TV*}Wu80;zT`jwW?@S46p!`GE<I-fn8W&*E%oqj
zs<c)989n#`p$-alMyPr$T5aJFnU)-q48W(>1Gs_rs^;VhehR<SQh0iM5tgwkItF)f
zA^H$ju)q2R{EbIya`5}DKWhNs5&l*CC9L7@*l{S~T<i&yk;k*}4?c<);cL9|LG!f3
zXf)MheyG5Jxtgzwp=n5o;uRk7R!<_4NfZ+1hdtR-3eqMF%6C$}lk%OEs}yGlcw6TM
zP~{$;A|&0m!P^A5B&k*XVm^~|vsjt1v<S}*oO64zBhj>NRdKUJnN>A+A(I*9?HEh!
z!V`)1_;YH?B}f?%qFWCn3?W=h{2?*Gfn*mf;%~`MVjp>muQ;Is2w<-4Xq!I1OeR|o
z1-4QEr{cWC4?1D02~ka@_%5E($H+FeY&(K>YVR~3p|?&(`!Z+pJnK%RdxOD8hC9-$
zwPP8cJv-5#dz<S&HJlsI@Br@N{0{0XEzLb%`MG@an~kNJe;2+lUH)Ych5qwr%Jbir
z7Vd0@^4s65EG;f?+`eIJVmI(=sz&1%se;%jS_!<LirYF68)=GJ#Dqz=5;p%gpc)j-
zd}RjQD6;-q0US=&Vx(?p=OuB#Bq`ds31J&T321y&s6L^_(65_O$H<K1&U!x;G<`*`
zEx*$glyY3J|6Jvi`w+VtPD~#q%VUE=;JnNYmzIBP*(oMFQjAT>jx1~sJjs(C<+@70
z1{+j-)luD$_&I#7!06M-w26|VZS~uF&$|@;SS<hgQ~Bz(jin_XOqgd(4RGPJhBSC+
zr8}awzR6jDu%3qF2BvFbCc%#jF91D`U!?1z)XrK2p(0@rp+wt!`dFplfeVB@kN3^G
z*f5#TNOC4AotdCpx~^N;(0Cy7vFMj5t^l9H@kU4GIr4C=u?42kYWlRI+1hPY>xaVX
E8%Nw5;Q#;t

delta 773
zcmZ8fT}V_x6rOWu?(WrfFE@AB)$6M3TE^B=P(&pZJxG6+FBXwRi+I;qA<em0O&bG|
zqPL<$1<}JU^b&*>K`;G)??pXC(Aq;qK_JvyP>FPAEr{+g-+Xg^=6v_eT;KPx+a8TZ
zYZ-m713C0_{R8`yv(u$*z!V>blHoxa=3quBp;(@KtdC`lUb&YdvO*rDMfPYoq+t*r
zJKHTm)Zw)TE;}#bHa=f-ky~;AFNae&RzDB-F&&$LM|dOl2A<(a{5!nBLc)i858oyL
zU=bG^PQrWaO7_Diyp~*oFF4y+gbFS-&Vz?Hn>u<F$h0zOa+-oBE18NbQ8s{Sh2+nX
zKS%x?`9fv($IeROzg(^(nOO@rxEZ|Uc4EKVjPvde=Np;*dV)F#(XepET`+zzTxi}6
z=dY&rM>YrC3n@_&UKsPK=ESamD$`ErJ^@pLI#h#qQd{vuDzQzD(ovO$iGnN+P38T<
z;J7RXQ~7}rf3hI6=KmdRrD%DW+UVlvNF1*uMGFTK)IfFzEU;+^(_W5);P#3Q_^RbX
z=eSOqB%t#qG_TX33(GSa`ZP#9*E(xTqBcTXDOF86OWQ2}C#f3h<I}cdrcXW>o6;wa
z?jfewF!LbEX1Hf)u0R=zd;FG3PlHt-iqMUigOVsS&n%Pd!1O}8CDlh0?v>S&W4a{i
z#2@K2OrhJ}6_Z1&wnkc36$kh((h}97YxUpj>%b@N$0J(4)WYN#rZerauS9*Dz+yI7
vb(UpC@JOa7x<zLhWEUW(@ovToRYXucUBE=gCYZ+VjsrCrXQLChx@*nf%-p&R

diff --git a/su/myproject/mqtt/forms.py b/su/myproject/mqtt/forms.py
index 332da0e..53971af 100644
--- a/su/myproject/mqtt/forms.py
+++ b/su/myproject/mqtt/forms.py
@@ -5,4 +5,10 @@
 class UserForm(forms.Form):
     username = forms.CharField(max_length=100)
     password = forms.CharField(widget=forms.PasswordInput)
-    confirm_password = forms.CharField(widget=forms.PasswordInput, required=False)
\ No newline at end of file
+    confirm_password = forms.CharField(widget=forms.PasswordInput, required=False)
+
+class ForgetPasswordForm(forms.Form):
+    username = forms.CharField(max_length=150, required=True, widget=forms.TextInput(attrs={'placeholder': '用户名'}))
+    question = forms.CharField(max_length=255, required=True, widget=forms.TextInput(attrs={'placeholder': '密保问题'}))
+    answer = forms.CharField(max_length=255, required=True, widget=forms.TextInput(attrs={'placeholder': '密保答案'}))
+    password = forms.CharField(max_length=128, required=True, widget=forms.PasswordInput(attrs={'placeholder': '要重置的密码'}))
\ No newline at end of file
diff --git a/su/myproject/mqtt/views.py b/su/myproject/mqtt/views.py
index d2f3c51..0bdc8e2 100644
--- a/su/myproject/mqtt/views.py
+++ b/su/myproject/mqtt/views.py
@@ -72,7 +72,7 @@ def register(request):
 
 #chat
 def chat(request):
-    username = u.userName  # 从session中获取username
+    username = u.userName
     if username:
         messages.info(request, f"欢迎回来 {username} (●’◡’●)")
     return render(request, 'chat.html')
@@ -105,4 +105,42 @@ def sendchat(request):
         return JsonResponse({'status': 'success','message': '发送成功'})
     return JsonResponse({'status': 'failed'})
 
+def setquestion(request):
+    if request.method == 'POST':
+        data = json.loads(request.body)
+        question = data.get('question')
+        answer = data.get('answer')
+        userName=u.userName
+        print("u.userName:"+u.userName)
+        print(question)
+        print(answer)
+        SecurityQuestion(u.userName,question=question,answer=answer)
+        time.sleep(2)
+        return JsonResponse({'status': 'success','message': '密保设置成功'})
+    return JsonResponse({'status': 'failed'})
+
+from .forms import ForgetPasswordForm
+
+def forgetpassword(request):
+    if request.method == 'POST':
+        form = ForgetPasswordForm(request.POST)
+        if form.is_valid():
+            username = form.cleaned_data['username']
+            question = form.cleaned_data['question']
+            answer = form.cleaned_data['answer']
+            password = form.cleaned_data['password']
+
+            s=SecurityQuestion(userName=username,question=question,answer=answer,new_password=password)
+            time.sleep(2)
+            if s.flag:
+                messages.error(request, '密码重置成功')
+                return redirect('login')
+            else:
+                messages.error(request, '用户名或密保错误或未设置密保,请重试')
+                return redirect('forgetpassword')
+
+
+    else:
+        form = ForgetPasswordForm()
 
+    return render(request, 'forgetpassword.html', {'form': form})
\ No newline at end of file
diff --git a/su/myproject/myproject/__pycache__/urls.cpython-310.pyc b/su/myproject/myproject/__pycache__/urls.cpython-310.pyc
index 47af1382b50962ccff13e171a7f75994899d00c5..3b09b60af3af46c35d35fd2d939487e4853dfde2 100644
GIT binary patch
delta 230
zcmbQk*~F!t&&$ij00i?ROVVbrFfcp@agYHIkmCTv#q%a=*Q%wmqzI<6W$~p5rLgxh
z19`$g9)F4mh?mY0C6FQ-%%CZ@aT6D_eHBk}YDr;fYH>+sexCj<ZX{k6e_DP~dTL2Q
zVsUYKeo>14Ek0BMKTW~O`<W9Iia@p(@dAlk+@(c11&JjksYQ9kD;bJ}K@!4~O<8>9
Wq<~Bo1|9((Mjl2!CLl(F96ta(9yn(J

delta 128
zcmZqTn!~A`&&$ij00aW8g=qpT3=EG!9Ap5JbpYbxrit3MT<L64d?|v#44Oh4&v7v`
z`)Tq|7H3HiyTx5vlv9vcQj%JfSG<y;ND!!@NO1CW7GEhbAd`iGM}UWshmns7h@p_<
F7XVwm75)GK

diff --git a/su/myproject/myproject/urls.py b/su/myproject/myproject/urls.py
index 73c3dc6..4b4033a 100644
--- a/su/myproject/myproject/urls.py
+++ b/su/myproject/myproject/urls.py
@@ -24,5 +24,7 @@
     path('register/', views.register, name='register'),
     path('getchats/', views.getchats, name='getchats'),
     path('sendchat/', views.sendchat, name='sendchat'),
+    path('setquestion/', views.setquestion, name='setquestion'),
+    path('forgetpassword/',views.forgetpassword,name='forgetpassword')
 
 ]
diff --git a/su/myproject/templates/chat.html b/su/myproject/templates/chat.html
index c780c79..e716436 100644
--- a/su/myproject/templates/chat.html
+++ b/su/myproject/templates/chat.html
@@ -17,26 +17,46 @@
         <el-container>
             <el-main style="position: relative;">
                 <el-menu :default-active="activeIndex" class="el-menu-demo" mode="horizontal" @select="handleSelect">
-                    <el-menu-item index="1">热门问答</el-menu-item>
+                    <el-menu-item index="1">讨论1区</el-menu-item>
                     <el-submenu index="2">
-                        <template slot="title">最新回答</template>
-                        <el-menu-item index="2-1">诊疗前沿</el-menu-item>
-                        <el-menu-item index="2-2">科普专区</el-menu-item>
-                        <el-menu-item index="2-3">专家评价</el-menu-item>
+                        <template slot="title">讨论2区</template>
                     </el-submenu>
-                    <el-menu-item index="3">我的关注</el-menu-item>
-                    <el-menu-item index="4">我的收藏</el-menu-item>
+                    <el-menu-item index="3">讨论2区</el-menu-item>
+                    <el-menu-item index="4">讨论3区</el-menu-item>
+                    <el-button v-if="!hasMessageTags" type="primary" class="login-button" @click="login">登入
+                    </el-button>
                 </el-menu>
+
+
                 <!-- 消息显示开始 -->
                 <div class="messages-container">
                     {% if messages %}
                     <ul class="messages">
                         {% for message in messages %}
-                        <li {% if message.tags %} class="{{ message.tags }}" {% endif %}>{{ message }}</li>
+                        <li class="{{ message.tags }}">
+                            {{ message }}
+                        </li>
                         {% endfor %}
                     </ul>
+                    <el-button @click="openSecurityDialog">设置密保</el-button>
                     {% endif %}
                 </div>
+
+                <el-dialog :visible.sync="dialogVisible" width="30%" :before-close="handleClose">
+                    <el-form :model="securityForm">
+                        <el-form-item label="密保问题">
+                            <el-input v-model="securityForm.question"></el-input>
+                        </el-form-item>
+                        <el-form-item label="密保答案">
+                            <el-input v-model="securityForm.answer"></el-input>
+                        </el-form-item>
+                    </el-form>
+                    <span slot="footer" class="dialog-footer">
+                    <el-button @click="dialogVisible = false">取 消</el-button>
+                    <el-button type="primary" @click="setSecurityQuestion">确 定</el-button>
+                    </span>
+                </el-dialog>
+
                 <!-- 消息显示结束 -->
                 <div class="line"></div>
                 <el-menu :default-active="activeIndex2" class="el-menu-demo" mode="horizontal" @select="handleSelect"
@@ -96,10 +116,18 @@ <h2 style="margin-bottom: 20px">聊天 {{ commentCount }}</h2>
             activeIndex2: '1',
             commentCount: 0,
             commentContent: '',
-            commentList: []
+            commentList: [],
+            hasMessageTags: false,
+            dialogVisible: false,
+            securityForm: {
+                question: '',
+                answer: ''
+            }
         },
         created() {
             this.fetchComments();
+            // 定时刷新评论区,每5秒刷新一次
+            setInterval(this.fetchComments, 1000);
         },
         methods: {
             handleSelect(key, keyPath) {
@@ -124,7 +152,6 @@ <h2 style="margin-bottom: 20px">聊天 {{ commentCount }}</h2>
                         'X-CSRFToken': this.getCookie('csrftoken')
                     },
                     body: JSON.stringify({
-
                         message: this.commentContent,
                     })
                 })
@@ -136,8 +163,8 @@ <h2 style="margin-bottom: 20px">聊天 {{ commentCount }}</h2>
                             });
                             this.fetchComments();
                             this.commentContent = '';
-                        }
-                        else if (data.status === 'failed' && data.message) {
+
+                        } else if (data.status === 'failed' && data.message) {
                             this.$alert(data.message, '提示', {
                                 confirmButtonText: '确定',
                             });
@@ -162,9 +189,45 @@ <h2 style="margin-bottom: 20px">聊天 {{ commentCount }}</h2>
                 }
                 return cookieValue;
             },
-            replyToComment(commentId) {
-                // 回复评论的处理逻辑,例如显示二级评论框
-                console.log('Reply to comment:', commentId);
+            openSecurityDialog() {
+            this.dialogVisible = true;
+        },
+        handleClose() {
+            this.dialogVisible = false;
+        },
+        setSecurityQuestion() {
+            fetch('/setquestion/', {
+                method: 'POST',
+                headers: {
+                    'Content-Type': 'application/json',
+                    'X-CSRFToken': this.getCookie('csrftoken')
+                },
+                body: JSON.stringify({
+                    question: this.securityForm.question,
+                    answer: this.securityForm.answer,
+                })
+            })
+            .then(response => response.json())
+            .then(data => {
+                if (data.status === 'success') {
+                    this.$alert(data.message, '提示', {
+                        confirmButtonText: '确定',
+                    });
+                } else if (data.status === 'failed' && data.message) {
+                    this.$alert(data.message, '提示', {
+                        confirmButtonText: '确定',
+                    });
+                }
+                this.dialogVisible = false;
+            })
+            .catch(error => {
+                console.error('Error setting security question:', error);
+                this.dialogVisible = false;
+            });
+
+            },
+            login() {
+                window.location.href = '/login';
             }
         }
     });
@@ -190,7 +253,20 @@ <h2 style="margin-bottom: 20px">聊天 {{ commentCount }}</h2>
     }
 
     .messages li {
-        margin-bottom: 5px;
+        margin-bottom: 23px;
+        text-align: center;
+        padding-top: 5px;
+    }
+
+    .el-menu-demo {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+    }
+
+    .login-button {
+        margin-left: auto;
+        margin-top: 10px;
     }
 </style>
 </body>
diff --git a/su/myproject/templates/forgetpassword.html b/su/myproject/templates/forgetpassword.html
new file mode 100644
index 0000000..954d9c2
--- /dev/null
+++ b/su/myproject/templates/forgetpassword.html
@@ -0,0 +1,131 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    {% load static %}
+    <meta charset="UTF-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <!-- 引入css文件 -->
+    <link rel="stylesheet" href="{% static 'css/login.css' %}">
+    <!-- 引入jquery -->
+    <script src="http://code.jquery.com/jquery-latest.js"></script>
+    <title>登录</title>
+</head>
+
+<body>
+    <!-- 最外层的大盒子 -->
+    <div class="box">
+        <!-- 滑动盒子 -->
+        <div class="pre-box">
+            <h1>WELCOME</h1>
+            <div class="img-box">
+                <img src="{% static 'img/waoku.jpg' %}" alt="">
+            </div>
+        </div>
+        <!-- 注册盒子 -->
+        <div class="register-form">
+            <!-- 标题盒子 -->
+            <div class="title-box">
+                <h1>注册</h1>
+            </div>
+            {% if messages %}
+                <ul class="messages">
+                    {% for message in messages %}
+                        <li class="{{ message.tags }}">{{ message }}</li>
+                    {% endfor %}
+                </ul>
+            {% endif %}
+        </div>
+        <!-- 登录盒子 -->
+        <div class="login-form">
+            <!-- 标题盒子 -->
+            <div class="title-box">
+                <h1>找回密码</h1>
+            </div>
+            <!-- 输入框盒子 -->
+            <form action="{% url 'forgetpassword' %}" method="post">
+                {% csrf_token %}
+                <div class="input-box">
+                    {{ form.username }}
+                    {{ form.question }}
+                    {{ form.answer }}
+                    {{ form.password }}
+                </div>
+                <!-- 按钮盒子 -->
+                <div class="btn-box">
+                    <button type="submit">确认</button>
+                    <p onclick="goLogin()" class="switch-link right-small">回到登入</p>
+                </div>
+            </form>
+        </div>
+    </div>
+
+    <script>
+       function goLogin() {
+            // Redirect to the forget password page
+            window.location.href = '{% url 'login' %}';
+        }
+
+        // Function to display error alert and refresh the form
+        const showAlertAndRefresh = (message) => {
+            alert(message);
+            location.reload();
+        }
+        {% if messages %}
+            {% for message in messages %}
+                {% if message.tags == 'error' %}
+                    showAlertAndRefresh("{{ message }}");
+                {% endif %}
+            {% endfor %}
+        {% endif %}
+    </script>
+    <script>
+           const bubleCreate = () => {
+        // 获取body元素
+        const body = document.body;
+        // 创建泡泡元素
+        const buble = document.createElement('span');
+        // 设置泡泡半径
+        let r = Math.random() * 5 + 25; // 半径大小为25~30
+        // 设置泡泡的宽高
+        buble.style.width = r + 'px';
+        buble.style.height = r + 'px';
+        // 设置泡泡的随机起点
+        buble.style.left = Math.random() * innerWidth + 'px';
+
+        // 检查泡泡是否生成在带有 'no-bubble' 类的元素或其子元素上
+        const noBubbleElements = document.querySelectorAll('.nobubble');
+        let isInsideNoBubbleElement = false;
+        noBubbleElements.forEach(element => {
+            const rect = element.getBoundingClientRect();
+            if (buble.style.left > rect.left && buble.style.left < rect.right) {
+                isInsideNoBubbleElement = true;
+            }
+        });
+
+        // 如果泡泡不在 'no-bubble' 元素上,添加泡泡到 body
+        if (!isInsideNoBubbleElement) {
+            body.append(buble);
+            // 4秒后清除泡泡
+            setTimeout(() => {
+                buble.remove();
+            }, 4000);
+        }
+    };
+
+    // 每200毫秒生成一个泡泡
+    setInterval(() => {
+        bubleCreate();
+    }, 200);
+</script>
+    <style>
+        .form-container {
+            margin-top: -50px; /* 向上移动 50 像素,可以根据需要调整 */
+            position: relative;
+        }
+    </style>
+
+</body>
+
+</html>
\ No newline at end of file
diff --git a/su/myproject/templates/login.html b/su/myproject/templates/login.html
index 9c00f5b..586e769 100644
--- a/su/myproject/templates/login.html
+++ b/su/myproject/templates/login.html
@@ -19,7 +19,6 @@
         <!-- 滑动盒子 -->
         <div class="pre-box">
             <h1>WELCOME</h1>
-            <p>JOIN US!</p>
             <div class="img-box">
                 <img src="{% static 'img/waoku.jpg' %}" alt="">
             </div>
@@ -78,8 +77,9 @@ <h1>登录</h1>
                 <div class="btn-box">
                     <button type="submit">登录</button>
                     <!-- 绑定点击事件 -->
-                    <p onclick="mySwitch()">没有账号?去注册</p>
+                    <p onclick="mySwitch()" class="switch-link">没有账号?去注册</p>
                 </div>
+                     <p onclick="goForget()" class="switch-link right-small">忘记密码</p>
             </form>
         </div>
     </div>
@@ -87,6 +87,10 @@ <h1>登录</h1>
     <script>
         // 滑动的状态
         let flag = true;
+             function goForget() {
+            // Redirect to the forget password page
+            window.location.href = '{% url 'forgetpassword' %}';
+        }
         const mySwitch = () => {
             if (flag) {
                 // 获取到滑动盒子的dom元素并修改它移动的位置
@@ -118,30 +122,55 @@ <h1>登录</h1>
         {% endif %}
     </script>
     <script>
-        const bubleCreate = () => {
-            // 获取body元素
-            const body = document.body;
-            // 创建泡泡元素
-            const buble = document.createElement('span');
-            // 设置泡泡半径
-            let r = Math.random() * 5 + 25 //半径大小为25~30
-            // 设置泡泡的宽高
-            buble.style.width = r + 'px';
-            buble.style.height = r + 'px';
-            // 设置泡泡的随机起点
-            buble.style.left = Math.random() * innerWidth + 'px';
-            // 为body添加buble元素
+
+           const bubleCreate = () => {
+        // 获取body元素
+        const body = document.body;
+        // 创建泡泡元素
+        const buble = document.createElement('span');
+        // 设置泡泡半径
+        let r = Math.random() * 5 + 25; // 半径大小为25~30
+        // 设置泡泡的宽高
+        buble.style.width = r + 'px';
+        buble.style.height = r + 'px';
+        // 设置泡泡的随机起点
+        buble.style.left = Math.random() * innerWidth + 'px';
+
+        // 检查泡泡是否生成在带有 'no-bubble' 类的元素或其子元素上
+        const noBubbleElements = document.querySelectorAll('.nobubble');
+        let isInsideNoBubbleElement = false;
+        noBubbleElements.forEach(element => {
+            const rect = element.getBoundingClientRect();
+            if (buble.style.left > rect.left && buble.style.left < rect.right) {
+                isInsideNoBubbleElement = true;
+            }
+        });
+
+        // 如果泡泡不在 'no-bubble' 元素上,添加泡泡到 body
+        if (!isInsideNoBubbleElement) {
             body.append(buble);
-            // 4s清除一次泡泡
+            // 4秒后清除泡泡
             setTimeout(() => {
                 buble.remove();
             }, 4000);
         }
-        // 每200ms生成一个泡泡
-        setInterval(() => {
-            bubleCreate();
-        }, 200);
-    </script>
+    };
+
+    // 每200毫秒生成一个泡泡
+    setInterval(() => {
+        bubleCreate();
+    }, 200);
+</script>
+<style>
+  .switch-link {
+    display: block;
+  }
+  .right-small {
+  color: white;           /* 字体颜色变为白色 */
+  margin-left: 185px;      /* 右移,可以根据需要调整距离 */
+  font-size: 12px;        /* 字体变小,例如 12px */
+}
+</style>
 </body>
 
 </html>
\ No newline at end of file