From ad767a806b85eef93d9209dc59d3b1076a19fabb Mon Sep 17 00:00:00 2001 From: kejingfan Date: Thu, 13 Jun 2024 13:53:54 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=AE=8C=E6=88=90=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E3=80=81=E6=B3=A8=E5=86=8C=E3=80=81=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E8=B4=A6=E5=8F=B7=E3=80=81=E4=B8=BB=E9=A1=B5=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Project/__pycache__/config.cpython-311.pyc | Bin 0 -> 1911 bytes Project/__pycache__/main.cpython-311.pyc | Bin 1423 -> 1479 bytes Project/db.sql | 128 ++++------- .../func/__pycache__/config.cpython-311.pyc | Bin 0 -> 1916 bytes .../func/__pycache__/index.cpython-311.pyc | Bin 408 -> 1245 bytes .../func/__pycache__/login.cpython-311.pyc | Bin 0 -> 2527 bytes .../func/__pycache__/modify.cpython-311.pyc | Bin 4841 -> 7616 bytes .../func/__pycache__/signup.cpython-311.pyc | Bin 2758 -> 3422 bytes Project/func/config.py | 18 ++ Project/func/index.py | 15 +- Project/func/login.py | 35 +++ Project/func/modify.py | 108 ++++++--- Project/func/signup.py | 63 ++++-- Project/func/verify_user.py | 35 --- Project/main.py | 74 ++++++- Project/static/css/index.css | 208 ++++++++++++++---- Project/static/css/login.css | 121 ++++++++++ Project/static/css/modify.css | 144 ++++++++++++ Project/static/css/signup.css | 71 ++++++ Project/static/css/style.css | 9 - .../static/images/banner-login-20200629.jpg | Bin 82495 -> 0 bytes Project/static/js/checkInfo.js | 54 +---- Project/static/js/index.js | 35 ++- Project/static/js/login.js | 81 +++++++ Project/static/js/modify.js | 19 +- Project/static/js/signup.js | 32 +++ Project/static/js/slideshow.js | 14 ++ Project/templates/index.html | 129 +++++++++-- Project/templates/login.html | 47 ++++ Project/templates/modify.html | 185 +++++++++------- Project/templates/signup.html | 154 ++++--------- 31 files changed, 1291 insertions(+), 488 deletions(-) create mode 100644 Project/__pycache__/config.cpython-311.pyc create mode 100644 Project/func/__pycache__/config.cpython-311.pyc create mode 100644 Project/func/__pycache__/login.cpython-311.pyc create mode 100644 Project/func/config.py create mode 100644 Project/func/login.py delete mode 100644 Project/func/verify_user.py create mode 100644 Project/static/css/login.css create mode 100644 Project/static/css/modify.css create mode 100644 Project/static/css/signup.css delete mode 100644 Project/static/css/style.css delete mode 100644 Project/static/images/banner-login-20200629.jpg create mode 100644 Project/static/js/login.js create mode 100644 Project/static/js/signup.js create mode 100644 Project/static/js/slideshow.js create mode 100644 Project/templates/login.html diff --git a/Project/__pycache__/config.cpython-311.pyc b/Project/__pycache__/config.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6b4d4367bddba3cd48763a514dc4a158f11fdcaa GIT binary patch literal 1911 zcmbuAO>g5w7{?ta?KWNdvP)TnI3c8!df0kqJho>L1@$HD!XiK6lV(F+Mmc=cx@=OaO+4HZ*;Zodu2OHIg9#fJ}lcO@;FQapC#q$<4-<91VZA_a=F*( z_73;ATV<=htu@MJR;~mPWw)L_Vg~>_T%rjp6e8sdi>SanBSS|!J zOg9f)o?J;fN4m^?v=0D`CW8NqG#FoxslMM}mSrLfIW{FGhJ<*4J2s>05>ezMr@}0L zyeSz*whNs(*(+cb$?@RESe1JO0WK)zP<1b+7!Z$Ojy%hufY{Qn-79{%DVBw>i>{|y zbZ9(zxfMtGjAYTTwQotk2u}YOp{>lKrU^NN4z?ZOF;75@JrCGen3UAU^=?cEvFjKL zV37W2GhW|Vl>^j~w!?viDD>3pf*GN}l7sZ3Fi4Y*$z$Qf4w}hnv zCXP>pZ9Bxl7LyqH)=fLqtaca^LIhq|`D(9T{N%EK*CI&o24$ia<$tz__EV;A9ubkH}fbIGViBjH;h>z^WU}S)xX2VL!+O@(s;3T z8waV7BFv00vM}M{Adny(L-pN|*<0>e b>w7g`n)A4R=wzWAD_i=RwmBQwT}AZ|eZ*n& literal 0 HcmV?d00001 diff --git a/Project/__pycache__/main.cpython-311.pyc b/Project/__pycache__/main.cpython-311.pyc index 6843b95900864ccad673180996488081c3e77d3a..48a1d3336bc48f17427642a42154ceab942202f9 100644 GIT binary patch delta 484 zcmeC@KF-a%oR^o20SGGFGt=%&ixJEV4zslUtaYd^v#%G?|J(-o3?EoSB|iT2KV?V-ZMu5g&*U zh7p25#%F|y*4MdZFLBFWcn3hHb9F?b5iY!l!4}e hBBA)tz>% diff --git a/Project/db.sql b/Project/db.sql index 9f284b4..50163fd 100644 --- a/Project/db.sql +++ b/Project/db.sql @@ -1,102 +1,58 @@ -DROP TABLE IF EXISTS Sold; -DROP TABLE IF EXISTS Transactions; -DROP TABLE IF EXISTS Passbys; DROP TABLE IF EXISTS Tickets; -DROP TABLE IF EXISTS Seats; +DROP TABLE IF EXISTS Flights; +DROP TABLE IF EXISTS Airports; DROP TABLE IF EXISTS Users; DROP TABLE IF EXISTS Passengers; -DROP TABLE IF EXISTS Rides; -DROP TABLE IF EXISTS Trains; -DROP TABLE IF EXISTS Stations; CREATE TABLE Passengers ( - ID BIGINT PRIMARY KEY, - `Name` VARCHAR ( 255 ) NOT NULL, - Phone_number BIGINT UNIQUE NOT NULL, - CHECK ( REGEXP_LIKE ( ID, '^\\d{18}$' ) ), - CHECK ( REGEXP_LIKE ( Phone_number, '^\\d{11}$' ) ) + ID BIGINT PRIMARY KEY, + `Name` VARCHAR(255) NOT NULL, + Phone_number BIGINT NOT NULL, + CHECK (REGEXP_LIKE(ID, '^\\d{18}$')), + CHECK (REGEXP_LIKE(Phone_number, '^\\d{11}$')) ); CREATE TABLE Users ( - ID INT AUTO_INCREMENT PRIMARY KEY, - `Password` VARCHAR ( 255 ) NOT NULL, - Phone_number BIGINT UNIQUE NOT NULL, - CitizenID BIGINT UNIQUE NOT NULL, - FOREIGN KEY ( Phone_number ) REFERENCES Passengers ( Phone_number ) ON DELETE CASCADE, - FOREIGN KEY ( CitizenID ) REFERENCES Passengers ( ID ) ON DELETE CASCADE + Phone_number BIGINT PRIMARY KEY, + Username VARCHAR(255) NOT NULL, + `Password` VARCHAR(255) NOT NULL, + CHECK (REGEXP_LIKE(Phone_number, '^\\d{11}$')) ); -CREATE TABLE Stations ( - ID INT AUTO_INCREMENT PRIMARY KEY, - `Name` VARCHAR ( 255 ) UNIQUE NOT NULL, - Province VARCHAR ( 255 ) NOT NULL, - City VARCHAR ( 255 ) NOT NULL +CREATE TABLE Airports ( + ID INT AUTO_INCREMENT PRIMARY KEY, + `Name` VARCHAR(255) UNIQUE NOT NULL, + Country VARCHAR(255) NOT NULL, + City VARCHAR(255) NOT NULL ); -CREATE TABLE Trains ( - ID VARCHAR ( 255 ) PRIMARY KEY, - TrainName VARCHAR ( 255 ) NOT NULL, - StationID_start INT NOT NULL, - StationID_arrive INT NOT NULL, - FOREIGN KEY ( StationID_start ) REFERENCES Stations ( ID ) ON DELETE CASCADE, - FOREIGN KEY ( StationID_arrive ) REFERENCES Stations ( ID ) ON DELETE CASCADE -); - -CREATE TABLE Seats ( - ID VARCHAR ( 255 ) PRIMARY KEY, - Type VARCHAR ( 255 ) NOT NULL, - TrainID VARCHAR ( 255 ) NOT NULL, - FOREIGN KEY ( TrainID ) REFERENCES Trains ( ID ) ON DELETE CASCADE +CREATE TABLE Flights ( + ID VARCHAR(255) PRIMARY KEY, + Airline VARCHAR(255) NOT NULL, + Departure_airport INT NOT NULL, + Arrival_airport INT NOT NULL, + Departure_time DATETIME NOT NULL, + Arrival_time DATETIME NOT NULL, + First_class_seats_remaining INT NOT NULL, -- 头等舱剩余座位 + Business_class_seats_remaining INT NOT NULL, -- 商务舱剩余座位 + Economy_class_seats_remaining INT NOT NULL, -- 经济舱剩余座位 + First_class_price DECIMAL(7, 2) NOT NULL, -- 头等舱价格 + Business_class_price DECIMAL(7, 2) NOT NULL, -- 商务舱价格 + Economy_class_price DECIMAL(7, 2) NOT NULL, -- 经济舱价格 + `Status` VARCHAR(255) NOT NULL CHECK (`Status` IN ('候机中', '延误', '已起飞', '已降落', '开始检票')), -- 航班状态 + FOREIGN KEY (Departure_airport) REFERENCES Airports(ID) ON DELETE CASCADE, + FOREIGN KEY (Arrival_airport) REFERENCES Airports(ID) ON DELETE CASCADE, + CHECK (Departure_time < Arrival_time) ); CREATE TABLE Tickets ( - ID INT AUTO_INCREMENT PRIMARY KEY, - Price DECIMAL ( 7, 2 ) NOT NULL, - Time_start DATETIME NOT NULL, - Time_arrive DATETIME NOT NULL, - StationID_start INT NOT NULL, - StationID_arrive INT NOT NULL, - SeatID VARCHAR ( 255 ) NOT NULL, - FOREIGN KEY ( StationID_start ) REFERENCES Stations ( ID ) ON DELETE CASCADE, - FOREIGN KEY ( StationID_arrive ) REFERENCES Stations ( ID ) ON DELETE CASCADE, - FOREIGN KEY ( SeatID ) REFERENCES Seats ( ID ) ON DELETE CASCADE, - CHECK ( Time_start <= Time_arrive ) -); - -CREATE TABLE Transactions ( - ID BIGINT AUTO_INCREMENT PRIMARY KEY, - `Time` DATETIME NOT NULL, - Paid TINYINT NOT NULL, - `User` INT NOT NULL, - PassengerID BIGINT NOT NULL, - TrainID VARCHAR ( 255 ) NOT NULL, - StationID_start INT NOT NULL, - StationID_arrive INT NOT NULL, - Time_start DATETIME NOT NULL, - Time_arrive DATETIME NOT NULL, - SeatID VARCHAR ( 255 ) NOT NULL, - FOREIGN KEY ( `User` ) REFERENCES Users ( ID ) ON DELETE CASCADE, - FOREIGN KEY ( PassengerID ) REFERENCES Passengers ( ID ) ON DELETE CASCADE, - FOREIGN KEY ( TrainID ) REFERENCES Trains ( ID ) ON DELETE CASCADE, - FOREIGN KEY ( StationID_start ) REFERENCES Stations ( ID ) ON DELETE CASCADE, - FOREIGN KEY ( StationID_arrive ) REFERENCES Stations ( ID ) ON DELETE CASCADE, - FOREIGN KEY ( SeatID ) REFERENCES Seats ( ID ) ON DELETE CASCADE, - CHECK ( Time_start < Time_arrive ) -); - -CREATE TABLE Sold ( - TransactionID BIGINT NOT NULL, - TicketID INT NOT NULL, - FOREIGN KEY ( TransactionID ) REFERENCES Transactions ( ID ) ON DELETE CASCADE, - FOREIGN KEY ( TicketID ) REFERENCES Tickets ( ID ) ON DELETE CASCADE -); - -CREATE TABLE Passbys ( - StationID INT NOT NULL, - TrainID VARCHAR ( 255 ) NOT NULL, - arrive_time DATETIME NOT NULL, - leave_time DATETIME NOT NULL, - FOREIGN KEY ( StationID ) REFERENCES Stations ( ID ) ON DELETE CASCADE, - FOREIGN KEY ( TrainID ) REFERENCES Trains ( ID ) ON DELETE CASCADE, - CHECK ( arrive_time <= leave_time ) + ID INT AUTO_INCREMENT PRIMARY KEY, + Price DECIMAL(7, 2) NOT NULL, + FlightID VARCHAR(255) NOT NULL, + Seat_class VARCHAR(255) NOT NULL, -- 级别信息 + PassengerID BIGINT NOT NULL, + Paid TINYINT NOT NULL, + FOREIGN KEY (FlightID) REFERENCES Flights(ID) ON DELETE CASCADE, + FOREIGN KEY (PassengerID) REFERENCES Passengers(ID) ON DELETE CASCADE, + CHECK (Seat_class IN ('First Class', 'Business Class', 'Economy Class')) ); \ No newline at end of file diff --git a/Project/func/__pycache__/config.cpython-311.pyc b/Project/func/__pycache__/config.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2bfd9d7b0846f782c42fa40ede31c9d867402136 GIT binary patch literal 1916 zcmbuAO>g5w7{?ta?KWNdvP)TnI3c8!df0kqJho>L1@$Gcuq!|$LZS%FcxLRl^-I=H zl*Xs!jNk~Dy(2yhQn^(=A@Kzw?X4%qPO@4m(W6lV(F+Mmc=cx@=OaO+4HZ*;Zodu2OHIg9#fJ}lcO@;FQapC#q$qfb9V1VZA_a=F*( z_73;ATV<=htu@MJR;~mPWw)L_Vg~>_T%rjp6e8sdi>SanBSS|!J zOg9f)o?J;fN4m^?v=0D`CW8NqG#FoxslMM}mSrLfIW{FGhJ<*4J2s>05>ezMr@}0L zyeSz*whNs(*(+cb$?@RESe1JO0WK)zP<1b+7!Z$Ojy%hufY{Qn-79{%DVBw>i>{|y zbZ9(zxfMtGjAYTTwQotk2u}YOp{>lKrU^NN4z?ZOF;75@JrCGen3UAU^=?cEvFjKL zV37W2GhW|Vl>^j~w!?viDD>3pf*GN}l7sZ3Fi4Y*$z$Qf4w}hnv zCXP>pZ9Bxl7LyqH)=fLqtaca^LIhq|`D(9T{N%EK*CI&o24$ia<$tz__EV;A9cPiH}fbIGViBjH;h>z^WU}S)xX2VW22wO(s;3T z8waV7BFv00vM}M{Ad1zIU$1#@pu`Z%*4w%lcGP@>HL$YwPbkU7ap#>))!J=Ieu| z3QJEGs%z`tRfRyGrLwx9R29Cd3PMlnRJu@A@T)?qPwG@L*Yh>5vTqDeTOb~cFS~DlZ$5tW=Dpv39U2-yU|*WG z$}f!2ZyCgvI0q*S0Co{U1iQ$?MeHSt2~R01o?28rt*Ci=QOAfRh~gTaSu_EwO;k)0 z4g3JnSCC~KOEOCrX-0iQSt+Dm-L*q13`U#Ib1r6nIY#!R?|Dd~7vI5E;Si(bd>esK#Rm)#Sd& z_+*%jF+ySL0+Yl(upIQ6u0|{93ZEYD+d|=Rj1k(x;pjy~luf*ezN`Ci`awT~6(}|o zO)Cf`|KN$x+@R|CuLc~b+{^j3&~vSX(9f@elnY@nBJsPeBgvnY6Rn9V* z3NxZuu4J<3OrB;XSXyG4AD2bRW=|J$Yk@~|>$K+h)r#%s?gd1)CHI&)e%YzJl$U}^ z>AoG>Pi;<1D;pe|39~^BI+v?7{BrIr)B1+cBE-gkS|-O=!EK|iG2DE;H~!O@Y8g}A z^vJvCJ%p3<-OR+N{O5doa<(%$+s@2&GIOoLxo&3c!<`+oJ9=YB@202rHh(-kTy3Qb z?R24&F0{--FNMtOKy(7!s4QJ28CVYfecB##TQV;4EJ^O~(I83sPT%m&$f=0+D zAQ*&~-v$Q-Ra4ESH_OfC?PUoU-zWEOwbg7#&9>BRH*9%C)r3-8dCS-*< m1J_e9#z*K;>wlgjG~K%T^i&-$;~u)?M-+UshyHd^PJaNnX$=$r literal 408 zcmZWkJx{|h5VeyON}~!!!~|QqV17Wv0vl3=)CIakCU!_#=R>wDQ6>idL-_@uia%2% z1{8^ji7isLPMkwPLY(Y(@7?*H?WcafhafKfIJ$uRVZ={ZEva{bED%Es3zXt9#)w(> zXlyZiga*#1Ikv>*w&WS(GSECN1l2rj$D3pWnqBV$ERe>K+FmY!GoZi zPk5+FG|NKrZC%XEPQ&CD7@IrP4!|9HclRFr7uS1ry_Mt1O(+frcG-ypRa5DJY$oJ} pVWum)0PC)w=4>YTv2;P2@2Dey%ElPKp@Y@mRXG?BD)b*3$1irYT;Tu! diff --git a/Project/func/__pycache__/login.cpython-311.pyc b/Project/func/__pycache__/login.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5b86723afd2fa092c11b7ba48829184757350835 GIT binary patch literal 2527 zcma)7O>7fK6rNr0de^ZX6I@~n`Ei7yxGi-BR1FC&YV!kx)KEfIVGzdgj*|^uui0HU z39@O3q7qO7X$vBiK;lr*RFog72l{sc4n3|TOIR!U)F!~Gk>~+&>YH^O?3Aj!Y~H*X zzxU0Xc|Y@=(^-Xp22T#eoGe0rkV%Q?Md3*&2$zt61S*asDnvXT4>tJ&UX~c4o29{)j7Lmr3))D%aI!9&bG<}s={)@D-m4PLz0kV@x*8unW z5_ZOtMrkTWXBdIXuxZOxYe}zsOtWd`8u)#E$#)8YE?2HolCObqy);1?E9mh{(=wq_ z5Af)h)U!f-EWs0ddOEs0+75X4^~(tyPNbw>tav;3@BPU8iHa4~`{}NZ{T-FRzUN)9 zdOrxZdynpmsOq4s2uHnSt@V54w;5b=SQ=K3#|D|utrmg3Q^{YqiR&O zi&3p@aS;#UXiCEdAH!Odcw(^8xU6D7XYi8TE5>n9Hdf+9R2fccSO_NU_ZkOn%V&bjjuu=`cCL_UCKL<8~3ig!~J9N7j zzAO8S<4AknS#$o-*+W-6mm71hZpk{g=A2tcI`fWK^xBQO-46;iM@G8xOx5Y&XmF}! zTFWxN9OKg&U*2AGe#hAzS$kd1UI%)h(mmRJDmWG#3FaC8bk}ItsqV4vk?y?RHL~Xk zxPYRBm56v|7RHB=a!?qhbr{PEgF0p=q_VoaJTgctOH6@IqaQ4l$=mZ^c+4W+yhcL5 zNY6`0U;J5|W!AI}X*H!C5tMP7uJjIy+oHNP_j4VA z7i=O`i6d0S=pL}v%F0w=w}X*jFJB9rEtp_cAUZTp8NRa;d-+~HXdTj4KiBsm<;@JE zt$n@%ji#bO!3|gXU%ebtaK-2-eGr;?hB*n%yEqO~gJ{Td5DiiSf`+joXjpc395_)` zEP{Sbiu)b$?eQ4mRP2lUp3p4ZMcmDio za_+|T+~t|Sew%o7>(0Z`pXW~hI{)L$+!qt`6K5WOb+agoU&4V77`#I26^hYdMR+cT zQcVCffARMGUoYctU#U`O|Xns~{BrvN8 zt0im=(W9_RfX&vUkk}Zkd2LDnWRh{}JKz=c46b_Yr$+?We$Cx>;ZUZr0tLb2pE-=iQzKL^*q@ zf~VoCO@AY#Hy+A*4(B|F^&=786VX>h@=gB9om0EBj)r{Wy2+h6M;!s_y20J%vKyOo z8=LjD+p_MKoV!JLv^*`iRxcnLb}HuuN6l2znOzgR#&;3h-TG@?`r18NcX!U+{d-h* zf2=!}e@}rHSOP=@58}OW0jdwK@2=C=wgKJUyao8Z4OQ)RmV0kEwRDGtKw2qQs!#&3soNX7B{ y%4V2C1d*BnwqT(sDvvt!m;3T)qyC~VkE%z^zXhv}TCsqZSnW!R+~te8>E1tUhG1C$ literal 0 HcmV?d00001 diff --git a/Project/func/__pycache__/modify.cpython-311.pyc b/Project/func/__pycache__/modify.cpython-311.pyc index ef647e51c0be6f0d142faab1648ba4734bb5d01a..0e4db8113ded86bfed36fb912e5ac1c5911d9798 100644 GIT binary patch literal 7616 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 LP(ZB#+Ccsf-=u$_ diff --git a/Project/func/__pycache__/signup.cpython-311.pyc b/Project/func/__pycache__/signup.cpython-311.pyc index 0ca3dfeaaaf265d472ea697974894c784c740031..a42224ee2c6b1ac5c686bae8643ae609c10bdf43 100644 GIT binary patch literal 3422 zcma)8e{2)i9e?NZ*=PIWOK`{!2ZCDy!4T>|r>+_a8YBTbAx=cX+D2Vn$9GOl?(FdH zJOZ;3n^^16Ai9;QQN>iZ0>(tObXz5&3T^+Csr+}&EX_J8Ql()x{54Am3H7hNcm7St z$n)Lv_r34u`}_U4Ki1Wm0cum0!=j{yfbLI5H$L5R8uok&iQ zqJBb808Yn|0wq!t6rusA7Yq{yj=BUUjGTT9I1P`m8mC@mAs^;==#zPIR`AQbYJ~im zC@;w>4S6mE`GBk%qfqb#Bk&P{WeC+U#mhc!(i^}!O3i=>61|TPQkq``SNQ3!>*GK! zq0s+ntVL@aIip1b8)PI?YMed>zMyU)&Ye=MU~D4|hJuCdE*zC2rxW*amuY?T&}q${HebqkSq%EMYqo2rMcEDUOO#iwLbGAw)s_8f#?%4@sdqqPBfUdZS zYb;k_dxaM>)#il&FIuMo-CJn4#Z4DXW5xfo#91&$z6H(_F`Ba#Yqgi#TC#_7RaLEu z?b>)=Y#G^WdQmoGM2rlQ>oQ6u>nnCE)H)A#R(SHR3e7dwW~p|x+4#o5y1Kj(HzDb& zbyl&t&bR+tHLj(U?akM3^L`iVU8(awx&$&}`>^|7GsVpR-?ol)d-s?DFz|?=9p$y}7pZdG^L%*1ozK-HUK* zOE=5GW$*qq_qW^G_ZARvZRu|IgMU1F|4R18mBQqCzHGtc9UC|~?(lfWM~cqvsrIK! zo5V%za=cs0^}Eh;1V1}+;?%&HW6v(B3ptKo=bG&PJ$55vT@{ zm!~5f#J7X0NB6X->L9ODqF)Y7tE9k(Rni|mry73Y7tqZP@qM5g0#PVMplamj_&^lh z`*e^;aK9j^rh&NtKP!hKVU?PNp|Gq{0U;vsNG2kRAsOP!3>vT&8b$#NE`&Zp2wuWhNjW=? zA5OTYBO>pb;ZKLcQ$c^&)feILhl*$&d%AyXbvl1vGoC2vKh5?lbbr=pMf|1}v|{g#EfMN9JS6niku9?S#6bcDz_f12M^e!GVqte{DV(C;Yotf^@gjZ?nN-_Jh7Hi_d zzuArzwj;&vPP4mHmd>=L6D#)+tG1Vuz02*2&7HEj(>AxlxU+S(`8OBdOz1KVwvStX z*ZSMGYi$Wb-axWUg3QwfB$Z*dT=ib|F20)FmSj^*cbe%|nC^_-@u}+*SIWLGZQpnM zNZS6&?K5fnfy7W^=;NzPSQ#eF zfN5TQX~oi}SlTkqQ$>Xt#(LF#**!nFFqjy8j>>X4W>a%jG`HuLTNKC96w{Yx`V^)Q ztMOd+%nvP~AXaT{e>k2zp4!%x-qw|}?N8hG=dGZQtr$uSK7CRL>RaLfdDacYl?XsP6ypwQ1TF4wntnWB1^2Dy zV@C3ROUE%CdB2B1^gneJ?t72WZaetaZuT4^zwLP4^BVbJ8-eHt+x4Eq;K6GYrVo*r zKHN0eNIGei3JQK{Mmu@5v#4@3Xr~NpK~}ZB^(XKckpOm~?gzR@jBrtbKMW6`A^yOX nCQ+9s34+LgUgbqk2H2I_Cj(3uwO?M}PY}&{@cbTjBQyU4zL!&N literal 2758 zcmcImU2M}<6uyoV+X*hAWHc>wtr0&ZP8%90;o4CP zN?<~0OS>Q#W1=sJXad#=Y3xq|O-M+Cu~!HAp|X^xDOGt|Bs2-}wCkja6RK`|+0pg& zxxU{$=Y03vAAi%(U;;=cho(aJ4FLS1HY%c9RbF%>s9LHBi4+_?FUIt0WMbtzdY@8h2)K-73nv-e|l$`U(dBslHP(fZb4!tZxN% zC(vq6QRgV{>U##80kilCFoPvY);L|tAAG+qGP>RdnhkxnLG!L@^|OH(tQTWLy~X+# zifrS*WhjXybxAy=Uy~<&cB2-LrmcyrcIM6X{xJ|8T$8Qd6opuuHH(_I#`Ztwt=99V z*F9IV6Q#;os>#m(J?8+OT8$nB?{|-%-5`V~qltLul*mUE{n)5?T%m#i$hu-Ir|6>r zo>M43HW7|+o|w|eMT786T;$lXfFR7oAbZwjVphfLKJ0dlGp^BNo^jhAJ9Fsh=m>L6 z;Gj@JFdq%LkGh$`KIQ3DxbFXhYTVSKlvR`mXTHmxYHH3J)Iq`7pD5^Y+TU zuM4++So!(3LX?9|>{Ou_77O=(T>fdX@M&h{(Ps#{a_@fO^GDA=yHvP!sr+3rgwcsS zdp2HmHR$oWkB&2gp7Bv8jyQ19Ni{&*U|$Dw(u3HZ>|n;GVo}Z?P4E*OL|-dZPuid09-WlN_-zg}JbFrrH9IP`*W=wa%)G<;*c#4iFQ3z2M#&FQ-`U)3xB$AZ+|ELd#3^E9y?Y3 zFPkpyw9?)y?H+C0l=fX|4Sow=AV&bI2hS_2myfZD2=^Yep{DwiCHPQP#4!w80)5hd WD@$OjR9}kv4s1^mtgYZ%$o${HwS!v# diff --git a/Project/func/config.py b/Project/func/config.py new file mode 100644 index 0000000..8e3c745 --- /dev/null +++ b/Project/func/config.py @@ -0,0 +1,18 @@ +db = { + 'host':'localhost', + 'user':'kejingfan', + 'password':'KJF2811879', + 'database':'TESTDB' +} + +SECRET_KEY = 'ILOVEDATABASETECH' + +slideshow_images = [ + {"link": "https://www.csair.com/mcms/mcms/SG/zh/2024/20240208_6/index-zh.html?lang=zh&country=sg&utm_campaign=2402gwstu&utm_source=gw&utm_channel=sg-lb", "src": "https://www.csair.com/mcms/20240321/3ee85acd463f481bb33f0d535a5814c6.jpg"}, + {"link": "https://www.csair.com/mcms/mcms/SG/zh/2024/20240605_10/index_sg_cn.html?lang=zh&country=sg&utm_source=sg&utm_campaign=ZB001lydc&utm_channel=gw", "src": "https://www.csair.com/mcms/20240605/a553252769834188b0c76a9698292f27.jpg"}, + {"link": "https://www.csair.com/mcms/mcms/SG/zh/2024/20240426_17/index_cn.html?lang=zh&country=sg&utm_source=sg&utm_campaign=ZB001znjp&utm_channel=gw", "src": "https://www.csair.com/mcms/20240321/820cd99c111849408b84c2b579086ef6.jpg"}, + {"link": "https://www.csair.com/mcms/mcms/SG/zh/2024/20240524_2/index_cn.html?lang=zh&country=sg&country=my&utm_source=us&utm_campaign=ZB001nhzgx&utm_channel=gw", "src": "https://www.csair.com/mcms/20240321/61889331ca174670babd144bb064d398.jpg"}, + {"link": "https://www.csair.com/mcms/mcms/SG/zh/2024/20240514_7/coupon.html?lang=zh&country=sg", "src": "https://www.csair.com/mcms/20240321/97e67c05291b4c64a8905e8a0c915d89.jpg"}, + {"link": "#", "src": "https://www.csair.com/mcms/1026/43124f5d5124487f8d6678745ae42f57.jpg"}, + {"link": "https://www.csair.com/mcms/mcms/SG/zh/2023/20231120_2/index_sg_cn.html?lang=zh&country=sg&utm_source=sg&utm_campaign=ZB001mq&utm_channel=gw", "src": "https://www.csair.com/mcms/1026/ea00e9cb9d9b43bea6497a6895c6d9e1.jpg"} +] diff --git a/Project/func/index.py b/Project/func/index.py index 64f8a9a..336daa4 100644 --- a/Project/func/index.py +++ b/Project/func/index.py @@ -1,4 +1,15 @@ -from flask import render_template +from flask import render_template, request, g, redirect, url_for, session +from .config import slideshow_images def index(): - return render_template("index.html") \ No newline at end of file + if request.method == 'GET': + if not g.user: + return redirect(url_for("login")) + username = g.name + images = slideshow_images + return render_template('index.html', images=images, username=username) + +def logout(): + session.clear() + session.pop('user_id', None) + return redirect(url_for('login')) diff --git a/Project/func/login.py b/Project/func/login.py new file mode 100644 index 0000000..4600888 --- /dev/null +++ b/Project/func/login.py @@ -0,0 +1,35 @@ +from flask import request, jsonify, session, url_for, render_template +from .config import db, slideshow_images +import pymysql + + +def connect(mobileNo, encrypted_password): + conn = pymysql.connect(**db) + cursor = conn.cursor(pymysql.cursors.DictCursor) + args = (mobileNo, encrypted_password) + verify_sql = "SELECT Phone_number FROM Users WHERE Phone_number = %s AND `Password` = %s;" + cursor.execute(verify_sql, args) + user = cursor.fetchone() + cursor.close() + conn.close() + return user + +def login(): + if request.method == 'GET': + images = slideshow_images + return render_template('login.html', images=images) + + if request.method == 'POST': + session.pop('user_id', None) + mobileNo = request.json.get('username') + encrypted_password = request.json.get('password') + try: + user = connect(mobileNo, encrypted_password) + if not user: + return jsonify({'message': '用户不存在,请点击注册按钮注册'}), 401 + session['user_id'] = mobileNo + session.modified = True + return jsonify({'redirect': url_for('index')}) + except Exception as e: + print(e) + return jsonify({'message': '数据库错误,请稍后再试'}), 500 diff --git a/Project/func/modify.py b/Project/func/modify.py index 474a028..ea628cb 100644 --- a/Project/func/modify.py +++ b/Project/func/modify.py @@ -1,79 +1,127 @@ -from flask import render_template, request, flash, redirect, url_for +from flask import render_template, request, flash, redirect, url_for, session from typing import Dict - +from pymysql.cursors import Cursor from .get_db import get_db -from .verify_user import verify_user +def get_current_user(cursor: Cursor, phone_number: str): + sql = "SELECT Username FROM Users WHERE Phone_number = %s" + cursor.execute(sql, (phone_number,)) + return cursor.fetchone() + +def verify_user(cursor: Cursor, phone_number: str, password: str) -> str: + sql = """ + SELECT Password FROM Users WHERE Phone_number = %s; + """ + cursor.execute(sql, (phone_number,)) + record = cursor.fetchone() + if not record: + return "NO_USER" + if record[0] != password: + return "WRONG_PASSWORD" + return "USER_VERIFIED" class ModifyInfo: - def __init__(self, form:Dict[str, str]): - self.id = form['cardCode'] + def __init__(self, form: Dict[str, str], user_phone: str): + self.phone_number = user_phone + print(form) modifyType = form['modifyType'] - self.new_password = form['encryptedNewPassword'] - self.phone_number = form['mobileNo'] + self.new_password = form.get('encryptedNewPassword', None) + self.new_phone_number = form.get('mobileNo', None) + self.new_username = form.get('username', None) modifyType2command = { - '1':'delete account', - '2':'modify Password', - '3':'modify Phone_Number' + '删除账户': 'delete account', + '修改密码': 'modify Password', + '修改手机号': 'modify Phone_Number', + '修改用户名': 'modify Username' } self.sql_dict = { - 'delete account': 'DELETE FROM passengers WHERE ID = %s;', - 'modify Password': 'UPDATE passengers SET `Password` = %s WHERE ID = %s;', - 'modify Phone_Number': 'UPDATE passengers SET Phone_number = %s WHERE ID = %s;' + 'delete account': 'DELETE FROM Users WHERE Phone_number = %s;', + 'modify Password': 'UPDATE Users SET Password = %s WHERE Phone_number = %s;', + 'modify Phone_Number': 'UPDATE Users SET Phone_number = %s WHERE Phone_number = %s;', + 'modify Username': 'UPDATE Users SET Username = %s WHERE Phone_number = %s;' } self.sql_args_dict = { - 'delete account': (self.id,), - 'modify Password': (self.new_password, self.id), - 'modify Phone_Number': (self.phone_number, self.id) + 'delete account': (self.phone_number,), + 'modify Password': (self.new_password, self.phone_number), + 'modify Phone_Number': (self.new_phone_number, self.phone_number), + 'modify Username': (self.new_username, self.phone_number) } self.ok_message_dict = { 'delete account': "删除账户成功", 'modify Password': "修改密码成功", - 'modify Phone_Number': "修改手机号成功" + 'modify Phone_Number': "修改手机号成功", + 'modify Username': "修改用户名成功" } self.fail_message_dict = { 'delete account': "数据库异常,删除账户失败", 'modify Password': "数据库异常,修改密码失败", - 'modify Phone_Number': "数据库异常,修改手机号失败" + 'modify Phone_Number': "数据库异常,修改手机号失败", + 'modify Username': "数据库异常,修改用户名失败" } self.command = modifyType2command[modifyType] + def get_sql(self): return self.sql_dict[self.command] + def get_args(self): return self.sql_args_dict[self.command] + def get_ok_message(self): return self.ok_message_dict[self.command] + def get_fail_message(self): return self.fail_message_dict[self.command] def modify(): if request.method == 'GET': - return render_template('modify.html') - + user_phone = session.get('user_id') + db = get_db() + cursor = db.cursor() + current_user = get_current_user(cursor, user_phone) + if not current_user: + session.clear() + return redirect(url_for('login')) + return render_template('modify.html', current_user_phone=user_phone, current_username=current_user[0]) + if request.method == 'POST': - id = request.form['cardCode'] + user_phone = session.get('user_id') password = request.form['encryptedPassword'] db = get_db() cursor = db.cursor() - verify_info = verify_user(cursor, id, password) - if (verify_info == "NO_USER"): - flash("您未注册过,无法修改账号") - db.close() - return redirect(url_for('signup')) - elif (verify_info == "WRONG_PASSWORD"): + verify_info = verify_user(cursor, user_phone, password) + if verify_info == "NO_USER": + session.clear() + return redirect(url_for('login')) + elif verify_info == "WRONG_PASSWORD": flash("密码错误") db.close() return redirect(url_for('modify')) - modifyInfo = ModifyInfo(request.form) + modifyInfo = ModifyInfo(request.form, user_phone) + + if modifyInfo.command == 'modify Phone_Number': + check_sql = "SELECT COUNT(*) FROM Users WHERE Phone_number = %s;" + cursor.execute(check_sql, (modifyInfo.new_phone_number,)) + if cursor.fetchone()[0] > 0: + flash("手机号已存在,请使用其他手机号") + db.close() + return redirect(url_for('modify')) + try: cursor.execute(modifyInfo.get_sql(), modifyInfo.get_args()) db.commit() flash(modifyInfo.get_ok_message()) + db.close() + if modifyInfo.command in ['modify Phone_Number', 'modify Password', 'delete account']: + session.clear() + session.pop("user_id", None) + return redirect(url_for('login')) + elif modifyInfo.command == 'modify Username': + return redirect(url_for('modify')) except Exception as e: db.rollback() print(e) flash(modifyInfo.get_fail_message()) - db.close() - return redirect(url_for('index')) \ No newline at end of file + db.close() + return redirect(url_for('modify')) diff --git a/Project/func/signup.py b/Project/func/signup.py index 38b217a..5cd61bb 100644 --- a/Project/func/signup.py +++ b/Project/func/signup.py @@ -1,15 +1,38 @@ -from flask import render_template, request, flash, redirect, url_for +from flask import render_template, request, redirect, url_for from .get_db import get_db +import re def signup(): + error_messages = { + 'username': '', + 'mobileNo': '', + 'password': '', + 'confirmPassword': '' + } + if request.method == 'GET': - return render_template('signup.html') + return render_template('signup.html', errors=error_messages) if request.method == 'POST': - id = request.form['cardCode'] - name = request.form['name'] + username = request.form['username'] phone_number = request.form['mobileNo'] password = request.form['encryptedPassword'] + confirm_password = request.form['encryptedConfirmPassword'] + + # Basic validation for phone number + if not re.match(r'^\d{11}$', phone_number): + error_messages['mobileNo'] = '手机号格式有误' + + # Check password length after MD5 hash + if len(password) != 32: # MD5 hash length is 32 characters + error_messages['password'] = '密码格式有误' + + # Confirm password validation + if password != confirm_password: + error_messages['confirmPassword'] = '两次输入的密码不一致' + + if any(error_messages.values()): + return render_template('signup.html', errors=error_messages) db = get_db() cursor = db.cursor() @@ -17,32 +40,34 @@ def signup(): # 检查已有用户 sql = """ SELECT COUNT(*) FROM Users \ - WHERE ID = %s; + WHERE Phone_number = %s; """ try: - cursor.execute(sql, (id,)) - id_exist = cursor.fetchall()[0][0] + cursor.execute(sql, (phone_number,)) + phone_exist = cursor.fetchall()[0][0] except Exception as e: - flash("数据库异常,查询失败") + error_messages['mobileNo'] = "数据库异常,查询失败" print(e) - return redirect(url_for('signup')) - if (id_exist != 0): - flash("您已注册过,请勿重复注册") + return render_template('signup.html', errors=error_messages) + + if phone_exist != 0: + error_messages['mobileNo'] = "该手机号已注册,请勿重复注册" db.close() - return redirect(url_for('index')) + return render_template('signup.html', errors=error_messages) # 插入 sql = ''' - INSERT INTO passengers (ID, `Name`, Phone_number, `Password`) \ - VALUES (%s, %s, %s, %s); \ + INSERT INTO Users (Phone_number, Username, `Password`) \ + VALUES (%s, %s, %s); \ ''' try: - cursor.execute(sql, (id, name, phone_number, password)) + cursor.execute(sql, (phone_number, username, password)) db.commit() - flash("注册成功") + return redirect(url_for('index')) except Exception as e: db.rollback() print(e) - flash("数据库异常,注册失败") - db.close() - return redirect(url_for('index')) \ No newline at end of file + error_messages['mobileNo'] = "数据库异常,注册失败" + return render_template('signup.html', errors=error_messages) + finally: + db.close() diff --git a/Project/func/verify_user.py b/Project/func/verify_user.py deleted file mode 100644 index 8201e9b..0000000 --- a/Project/func/verify_user.py +++ /dev/null @@ -1,35 +0,0 @@ -from flask import flash, redirect, url_for -from pymysql.cursors import Cursor - -def verify_user(cursor:Cursor, id:str, password:str) -> str: - # 检查已有用户 - sql = """ - SELECT COUNT(*) FROM passengers \ - WHERE ID = %s; - """ - try: - cursor.execute(sql, (id,)) - id_exist = cursor.fetchall()[0][0] - except Exception as e: - flash("数据库异常,查询失败") - print(e) - return redirect(url_for('signup')) - if (id_exist == 0): - return "NO_USER" - - # 检查密码 - sql = """ - SELECT `Password` FROM passengers \ - WHERE ID = %s; - """ - try: - cursor.execute(sql, (id,)) - record_password = cursor.fetchall()[0][0] - except Exception as e: - flash("数据库异常,查询失败") - print(e) - return redirect(url_for('modify')) - if (record_password != password): - return "WRONG_PASSWORD" - - return "USER_VERIFIED" \ No newline at end of file diff --git a/Project/main.py b/Project/main.py index 623f790..9da23de 100644 --- a/Project/main.py +++ b/Project/main.py @@ -1,22 +1,80 @@ -from flask import Flask -import os +from flask import Flask, redirect, url_for, session, render_template, request, g +from flask_httpauth import HTTPTokenAuth +from flask_cors import CORS +from func.config import db, SECRET_KEY, slideshow_images +import pymysql -import func.index +import func.login import func.signup import func.modify +import func.index -app = Flask(__name__) -app.secret_key = os.environ.get('SECRET_KEY', 'OPTIONALSECRETKEY') +app = Flask(__name__) +app.config["SECRET_KEY"] = SECRET_KEY +app.config["JSON_AS_ASCII"] = False +app.config['SESSION_COOKIE_HTTPONLY'] = True +app.config['SESSION_COOKIE_SECURE'] = False +app.config['SESSION_COOKIE_SAMESITE'] = 'Lax' +CORS(app, supports_credentials=True) +auth = HTTPTokenAuth(scheme='Bearer') +@app.before_request +def before_request(): + g.user = None + g.name = None + if 'user_id' in session: + conn = pymysql.connect(**db) + cursor = conn.cursor(pymysql.cursors.DictCursor) + args = (session.get('user_id'),) + verify_sql = "SELECT Phone_number, Username FROM Users WHERE Phone_number = %s;" + cursor.execute(verify_sql, args) + res = cursor.fetchone() + if not res: + g.user = None + g.name = None + else: + g.user = res['Phone_number'] + g.name = res['Username'] @app.route("/") +def home(): + return redirect(url_for('index')) + +@app.route("/index", methods=['GET', 'POST']) def index(): return func.index.index() -@app.route("/signup.html", methods=('GET', 'POST')) +@app.route("/login", methods=['GET', 'POST']) +def login(): + return func.login.login() + +@app.route('/logout') +def logout(): + return func.index.logout() + +@app.route("/signup", methods=['GET', 'POST']) def signup(): return func.signup.signup() -@app.route("/modify.html", methods=('GET', 'POST')) +@app.route("/modify", methods=['GET', 'POST']) def modify(): - return func.modify.modify() \ No newline at end of file + if request.method == 'GET': + if not g.user: + return redirect(url_for("login")) + return func.modify.modify() + +@app.route("/search", methods=['GET']) +def search(): + # 处理搜索逻辑 + return "搜索结果" + +@app.route("/orders", methods=['GET', 'POST']) +def orders(): + return "我的订单" + +if __name__ == "__main__": + app.run( + host="0.0.0.0", + port=5000, + debug=True + ) diff --git a/Project/static/css/index.css b/Project/static/css/index.css index f9854f9..3943054 100644 --- a/Project/static/css/index.css +++ b/Project/static/css/index.css @@ -7,53 +7,124 @@ body { display: flex; flex-direction: column; align-items: center; + overflow-x: hidden; /* 防止出现水平滚动条 */ } header { + display: flex; + justify-content: space-between; + align-items: center; background-color: rgba(28, 108, 178, 0.9); color: white; - padding: 20px 0; - text-align: center; + padding: 20px; width: 100%; } -nav ul { - list-style: none; - padding: 0; - margin: 0; +.header-content { + display: flex; + align-items: center; + width: 100%; + justify-content: space-between; } -nav ul li { - display: inline; - margin: 0 10px; +.logo { + font-size: 24px; + font-weight: bold; + margin-left: 20px; } -nav ul li a { +.nav-buttons { + display: flex; + gap: 20px; +} + +.nav-buttons a { color: white; text-decoration: none; - font-weight: bold; + font-size: 16px; + padding: 10px; + border-radius: 5px; } -main { - flex: 1; - display: flex; - align-items: center; - justify-content: center; - width: 100%; +.nav-buttons a:hover { + background-color: #155a8c; } -.background-container { - width: 100%; - max-width: 1500px; - height: 600px; /* Adjust according to the desired size */ - background-image: url('/static/images/banner-login-20200629.jpg'); - background-size: cover; - background-position: center; - background-repeat: no-repeat; - display: flex; - align-items: center; - justify-content: center; +.user-menu { position: relative; + display: flex; + align-items: center; + margin-right: 20px; +} + +.user-menu span { + margin-right: 10px; +} + +.dropdown { + position: relative; + display: inline-block; +} + +.dropbtn { + background-color: rgba(28, 108, 178, 0.9); + color: white; + border: none; + cursor: pointer; + font-size: 16px; +} + +.dropdown-content { + display: none; + position: absolute; + background-color: #f9f9f9; + min-width: 160px; + box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); + z-index: 1; + right: 0; /* 确保下拉菜单靠右对齐 */ +} + +.dropdown-content a { + color: black; + padding: 12px 16px; + text-decoration: none; + display: block; +} + +.dropdown-content a:hover { + background-color: #f1f1f1; +} + +.dropdown:hover .dropdown-content { + display: block; +} + +.slides { + position: relative; + width: 100%; + height: 400px; + overflow: hidden; +} + +.slides ul { + display: flex; + padding: 0; + width: 100%; + height: 100%; + list-style: none; + margin: 0; + transition: transform 0.6s ease-in-out; +} + +.slides li { + min-width: 100%; + box-sizing: border-box; +} + +.slides img { + width: 100%; + height: 100%; + object-fit: cover; } .content { @@ -61,28 +132,79 @@ main { padding: 20px; border-radius: 10px; text-align: center; - position: absolute; + width: 80%; + max-width: 800px; + margin: -50px auto 20px; + position: relative; } -h2 { - color: #1c6cb2; +.tabcontent { + display: block; + padding: 20px; } -.links { - margin-top: 20px; +.form-row { + display: flex; + justify-content: space-between; + margin-bottom: 15px; } -.links .btn { +.form-row label { + flex: 1; + margin-right: 10px; + text-align: right; + line-height: 32px; +} + +.form-row input, +.form-row select { + flex: 2; + padding: 8px; + font-size: 16px; + border: 1px solid #ccc; + border-radius: 5px; +} + +.passenger-input { + display: flex; + align-items: center; + gap: 5px; +} + +.passenger-input button { + padding: 5px 10px; + font-size: 18px; background-color: #1c6cb2; color: white; - padding: 10px 20px; - text-decoration: none; + border: none; border-radius: 5px; - margin: 10px; - display: inline-block; + cursor: pointer; } -.links .btn:hover { +.passenger-input button:hover { + background-color: #155a8c; +} + +.passenger-input input { + width: 50px; + text-align: center; + font-size: 16px; + border: 1px solid #ccc; + border-radius: 5px; +} + +.btn { + padding: 10px 20px; + background-color: #1c6cb2; + color: white; + border: none; + border-radius: 5px; + text-decoration: none; + display: inline-block; + cursor: pointer; +} + +.btn:hover { background-color: #155a8c; } @@ -92,4 +214,12 @@ footer { text-align: center; padding: 10px 0; width: 100%; + margin-top: auto; +} + +.error-message { + color: red; + font-size: 12px; + text-align: left; + margin-top: 5px; } diff --git a/Project/static/css/login.css b/Project/static/css/login.css new file mode 100644 index 0000000..ac9ce9b --- /dev/null +++ b/Project/static/css/login.css @@ -0,0 +1,121 @@ +body { + font-family: Arial, sans-serif; + margin: 0; + padding: 0; + background-color: #ffffff; + height: 100vh; + display: flex; + flex-direction: column; + align-items: center; +} + +header { + background-color: rgba(28, 108, 178, 0.9); + color: white; + padding: 20px 0; + text-align: center; + width: 100%; +} + +main { + flex: 1; + display: flex; + align-items: center; + justify-content: center; + width: 100%; + position: relative; +} + +.slides { + position: relative; + width: 100%; + height: 600px; + overflow: hidden; +} + +.slides ul { + display: flex; + padding: 0; + width: 100%; + height: 100%; + list-style: none; + margin: 0; + transition: transform 0.6s ease-in-out; +} + +.slides li { + min-width: 100%; + box-sizing: border-box; +} + +.slides img { + width: 100%; + height: 100%; + object-fit: cover; +} + +.content { + background-color: rgba(255, 255, 255, 0.8); + padding: 20px; + border-radius: 10px; + text-align: center; + position: absolute; +} + +h2 { + color: #1c6cb2; +} + +.login-form { + margin-bottom: 20px; +} + +.login-form input { + display: block; + margin: 10px auto; + padding: 10px; + font-size: 16px; + width: 80%; + max-width: 300px; + margin-bottom: 20px; /* 增加外边距 */ +} + +.buttons { + display: flex; + justify-content: center; + gap: 10px; +} + +.login-form button, +.btn { + padding: 10px 20px; + background-color: #1c6cb2; + color: white; + border: none; + border-radius: 5px; + text-decoration: none; + display: inline-block; + line-height: 20px; + cursor: pointer; +} + +.login-form button:hover, +.btn:hover { + background-color: #155a8c; +} + +footer { + background-color: rgba(28, 108, 178, 0.9); + color: white; + text-align: center; + padding: 10px 0; + width: 100%; +} + +.error-message { + color: red; + font-size: 12px; + text-align: left; + margin-top: -10px; + margin-bottom: 10px; +} diff --git a/Project/static/css/modify.css b/Project/static/css/modify.css new file mode 100644 index 0000000..8f0fb54 --- /dev/null +++ b/Project/static/css/modify.css @@ -0,0 +1,144 @@ +body { + font-family: Arial, sans-serif; + margin: 0; + padding: 0; + background-color: #ffffff; + height: 100vh; + display: flex; + flex-direction: column; + align-items: center; +} + +header { + background-color: rgba(28, 108, 178, 0.9); + color: white; + padding: 20px 0; + width: 100%; +} + +.header-content { + display: flex; + align-items: center; + justify-content: space-between; + width: 90%; + margin: 0 auto; + position: relative; +} + +.header-content .btn-back { + padding: 10px 20px; + background-color: #1c6cb2; + color: white; + border: none; + border-radius: 5px; + text-decoration: none; +} + +.header-content .btn-back:hover { + background-color: #155a8c; +} + +.header-content h1 { + position: absolute; + left: 50%; + transform: translateX(-50%); +} + +.header-content .header-spacer { + width: 100px; /* 占位符,确保标题居中 */ +} + +main { + flex: 1; + display: flex; + align-items: center; + justify-content: center; + width: 100%; + position: relative; +} + +.content { + background-color: rgba(255, 255, 255, 0.9); + padding: 30px; + border-radius: 10px; + text-align: center; + width: 400px; + position: relative; +} + +h2 { + color: #1c6cb2; +} + +form { + margin-top: 20px; +} + +.tab { + display: flex; + justify-content: space-around; + margin-bottom: 20px; +} + +.tab button { + background-color: #f1f1f1; + border: none; + outline: none; + cursor: pointer; + padding: 10px 20px; + transition: 0.3s; + font-size: 17px; + border-radius: 5px; +} + +.tab button:hover { + background-color: #ddd; +} + +.tab button.active { + background-color: #1c6cb2; + color: white; +} + +.tabcontent { + display: none; +} + +.form-group { + margin-bottom: 15px; + text-align: left; +} + +.form-group div { + margin-bottom: 5px; + font-weight: bold; +} + +.form-group input { + width: 100%; + padding: 10px; + box-sizing: border-box; +} + +button[type="submit"] { + padding: 10px 20px; + background-color: #1c6cb2; + color: white; + border: none; + border-radius: 5px; + cursor: pointer; + width: 100%; + font-size: 16px; +} + +button[type="submit"]:hover { + background-color: #155a8c; +} + +footer { + background-color: rgba(28, 108, 178, 0.9); + color: white; + text-align: center; + padding: 10px 0; + width: 100%; +} diff --git a/Project/static/css/signup.css b/Project/static/css/signup.css new file mode 100644 index 0000000..7946c39 --- /dev/null +++ b/Project/static/css/signup.css @@ -0,0 +1,71 @@ +body { + font-family: Arial, sans-serif; + margin: 0; + padding: 0; + background-color: #ffffff; + height: 100vh; + display: flex; + flex-direction: column; + align-items: center; +} + +form { + background-color: rgba(255, 255, 255, 0.9); + padding: 40px; /* 增加内边距 */ + border-radius: 10px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); + width: 100%; + max-width: 500px; /* 增大表单框的最大宽度 */ + margin: auto; + margin-top: 100px; +} + +ul { + list-style-type: none; + padding: 0; + margin: 0; +} + +li { + margin-bottom: 20px; +} + +div { + display: flex; + flex-direction: column; +} + +div div { + flex: 1; + padding-top: 5px; +} + +input[type="text"], input[type="password"] { + width: 100%; + padding: 10px; + font-size: 16px; + border: 1px solid #ccc; + border-radius: 5px; +} + +button { + width: 100%; + padding: 10px; + background-color: #1c6cb2; + color: white; + border: none; + border-radius: 5px; + font-size: 16px; + cursor: pointer; +} + +button:hover { + background-color: #155a8c; +} + +.error-message { + color: red; + font-size: 12px; + height: 12px; + margin-top: 5px; +} diff --git a/Project/static/css/style.css b/Project/static/css/style.css deleted file mode 100644 index 34abe50..0000000 --- a/Project/static/css/style.css +++ /dev/null @@ -1,9 +0,0 @@ -/* h1, ul, li, a, body { - margin: 0; - padding: 0; - text-decoration: none; -} */ - -li { - list-style: none; -} \ No newline at end of file diff --git a/Project/static/images/banner-login-20200629.jpg b/Project/static/images/banner-login-20200629.jpg deleted file mode 100644 index 21677f45043b3924013aa397dd5137eea7f13d87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 82495 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 diff --git a/Project/static/js/checkInfo.js b/Project/static/js/checkInfo.js index 641c012..d81ebe4 100644 --- a/Project/static/js/checkInfo.js +++ b/Project/static/js/checkInfo.js @@ -1,51 +1,15 @@ -var checkInfo = {} - -checkInfo.checkCardCode = function() { - let cardCode = document.getElementById('cardCode').value - let regexCardCode = /^([1-6][1-9]|50)\d{4}(18|19|20)\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/ - if(!regexCardCode.test(cardCode)) { - alert('身份证号格式有误') - return false - } - return true -} +var checkInfo = {}; checkInfo.checkMobileNo = function() { - let mobileNo = document.getElementById('mobileNo').value - let regexMobileNo = /^1[3-9]\d{9}$/ - if (!regexMobileNo.test(mobileNo)) { - alert('手机号格式有误') - return false - } - return true + let mobileNo = document.getElementById('mobileNo').value; + let regexMobileNo = /^1[3-9]\d{9}$/; + return regexMobileNo.test(mobileNo); } checkInfo.checkPassword = function() { - let password = document.getElementById('password') - let regexPassword = /^[A-Za-z0-9\W_]{6,20}$/ - if (!regexPassword.test(password.value)) { - alert("密码须为长度为6-20位字母、数字或符号") - return false - } - let confirmPassword = document.getElementById('confirmPassword') - if (password.value !== confirmPassword.value) { - alert("两次输入的密码不一致") - return false - } - return true + let password = document.getElementById('password').value; + let regexPassword = /^[A-Za-z0-9\W_]{6,20}$/; + let isValidPassword = regexPassword.test(password); + let confirmPassword = document.getElementById('confirmPassword').value; + return isValidPassword && (password === confirmPassword); } - -checkInfo.checkNewPassword = function() { - let password = document.getElementById('newPassword') - let regexPassword = /^[A-Za-z0-9\W_]{6,20}$/ - if (!regexPassword.test(password.value)) { - alert("密码须为长度为6-20位字母、数字或符号") - return false - } - let confirmPassword = document.getElementById('confirmNewPassword') - if (password.value !== confirmPassword.value) { - alert("两次输入的密码不一致") - return false - } - return true -} \ No newline at end of file diff --git a/Project/static/js/index.js b/Project/static/js/index.js index 7190b81..6e16fa8 100644 --- a/Project/static/js/index.js +++ b/Project/static/js/index.js @@ -1,8 +1,29 @@ -window.onload = function() { - // Display flashed messages, if any - const messages = []; - // Assuming messages are added via server-side templating - if (messages.length > 0) { - alert(messages.join("\n")); +function openTab(evt, tabName) { + var i, tabcontent, tablinks; + tabcontent = document.getElementsByClassName("tabcontent"); + for (i = 0; i < tabcontent.length; i++) { + tabcontent[i].style.display = "none"; } -}; + tablinks = document.getElementsByClassName("tablinks"); + for (i = 0; i < tablinks.length; i++) { + tablinks[i].className = tablinks[i].className.replace(" active", ""); + } + document.getElementById(tabName).style.display = "block"; + evt.currentTarget.className += " active"; +} + +function increment() { + var passengers = document.getElementById("passengers"); + var value = parseInt(passengers.value, 10); + if (value < 50) { + passengers.value = value + 1; + } +} + +function decrement() { + var passengers = document.getElementById("passengers"); + var value = parseInt(passengers.value, 10); + if (value > 1) { + passengers.value = value - 1; + } +} diff --git a/Project/static/js/login.js b/Project/static/js/login.js new file mode 100644 index 0000000..bed1617 --- /dev/null +++ b/Project/static/js/login.js @@ -0,0 +1,81 @@ +window.onload = function() { + autoLogin(); +}; + +var checkInfo = {}; + +checkInfo.checkMobileNo = function() { + let mobileNo = document.getElementById('mobileNo').value; + let regexMobileNo = /^1[3-9]\d{9}$/; + if (!regexMobileNo.test(mobileNo)) { + document.getElementById('mobileNoError').textContent = '手机号格式有误'; + return false; + } + document.getElementById('mobileNoError').textContent = ''; + return true; +} + +checkInfo.checkPassword = function() { + let password = document.getElementById('password').value; + let regexPassword = /^[A-Za-z0-9\W_]{6,20}$/; + if (!regexPassword.test(password)) { + document.getElementById('loginError').textContent = "密码须为长度为6-20位字母、数字或符号"; + return false; + } + document.getElementById('loginError').textContent = ''; + return true; +} + +function submitForm() { + if (checkInfo.checkMobileNo() && checkInfo.checkPassword()) { + document.getElementById('encryptedPassword').value = md5( + document.getElementById('password').value + ); + login(); + return true; + } + return false; +} + +// 登录函数 +async function login() { + const mobileNo = document.getElementById('mobileNo').value; + const encryptedPassword = document.getElementById('encryptedPassword').value; + try { + const response = await fetch('/login', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ username: mobileNo, password: encryptedPassword }), + credentials: 'include' // 确保请求包含凭据(cookies) + }); + const data = await response.json(); + if (response.ok) { + alert('登录成功'); + // 自动跳转到主页 + window.location.href = data.redirect; + } else { + document.getElementById('loginError').textContent = data.message; + } + } catch (error) { + alert('数据库错误,请稍后再试'); + } +} + +// 自动登录函数 +async function autoLogin() { + const token = localStorage.getItem('token'); + if (token) { + const response = await fetch('http://localhost:5000/index', { + headers: { + 'Authorization': 'Bearer ' + token + } + }); + if (response.ok) { + document.getElementById('content').innerText = '已自动登录'; + } else { + document.getElementById('content').innerText = '自动登录失败'; + } + } +} diff --git a/Project/static/js/modify.js b/Project/static/js/modify.js index 084e9f4..5dd6957 100644 --- a/Project/static/js/modify.js +++ b/Project/static/js/modify.js @@ -1,28 +1,31 @@ -var modify = {} +var modify = {}; modify.showModifyPassword = function() { - let modifyType = document.getElementById('modifyType').value + let modifyType = document.querySelector('.tablinks.active').textContent; let info = { modifyPasswordLis: document.getElementsByClassName('modifyPassword'), modifymobileNoLis: document.getElementsByClassName('modifymobileNo'), + modifyUsernameLis: document.getElementsByClassName('modifyUsername'), } - // 遍历隐藏所有元素 for (let key in info) { let elements = info[key]; for (let item of elements) { - item.style.display = 'none'; // 确保所有相关元素被隐藏 + item.style.display = 'none'; } } - // 根据 modifyType 显示相关元素 - if (modifyType === "2") { + if (modifyType === "修改密码") { for (let item of info.modifyPasswordLis) { item.style.display = 'block'; } - } else if (modifyType === "3") { + } else if (modifyType === "修改手机号") { for (let item of info.modifymobileNoLis) { item.style.display = 'block'; } + } else if (modifyType === "修改用户名") { + for (let item of info.modifyUsernameLis) { + item.style.display = 'block'; + } } -} \ No newline at end of file +} diff --git a/Project/static/js/signup.js b/Project/static/js/signup.js new file mode 100644 index 0000000..bf0ba4f --- /dev/null +++ b/Project/static/js/signup.js @@ -0,0 +1,32 @@ +function submitForm() { + let isValid = true; + clearErrors(); + + if (!checkInfo.checkMobileNo()) { + document.getElementById('mobileNoError').innerText = '手机号格式有误'; + isValid = false; + } + + if (!checkInfo.checkPassword()) { + document.getElementById('passwordError').innerText = '密码须为长度为6-20位字母、数字或符号'; + document.getElementById('confirmPasswordError').innerText = '两次输入的密码不一致'; + isValid = false; + } + + if (isValid) { + document.getElementById('encryptedPassword').value = md5( + document.getElementById('password').value + ); + document.getElementById('encryptedConfirmPassword').value = md5( + document.getElementById('confirmPassword').value + ); + return true; + } + return false; +} + +function clearErrors() { + document.getElementById('mobileNoError').innerText = ''; + document.getElementById('passwordError').innerText = ''; + document.getElementById('confirmPasswordError').innerText = ''; +} diff --git a/Project/static/js/slideshow.js b/Project/static/js/slideshow.js new file mode 100644 index 0000000..c7af2c5 --- /dev/null +++ b/Project/static/js/slideshow.js @@ -0,0 +1,14 @@ +let slideIndex = 0; +const slides = document.getElementById('slide-container'); +const totalSlides = slides.children.length; + +function showSlides() { + slideIndex++; + if (slideIndex >= totalSlides) { + slideIndex = 0; + } + slides.style.transform = 'translateX(' + (-slideIndex * 100) + '%)'; + setTimeout(showSlides, 5000); // Change image every 5 seconds +} + +showSlides(); diff --git a/Project/templates/index.html b/Project/templates/index.html index a9783d0..2b5f51e 100644 --- a/Project/templates/index.html +++ b/Project/templates/index.html @@ -3,34 +3,129 @@ - 我的12306官网 + KJF航班订票 +
-

中国铁路12306

- +
+ + +
+ {{ username }} + +
+
-
-
-

尽享精彩出行服务

- +
+
    + {% for image in images %} +
  • + + + +
  • + {% endfor %} +
+
+
+
+
+
+ + +
+
+ + +
+
+
+ + +
+
+ +
+ + + +
+
+
+ +
+
-

© 2024 中国铁路12306. 保留所有权利。

+

© 2024 KJF航班订票. 保留所有权利。

+ + diff --git a/Project/templates/login.html b/Project/templates/login.html new file mode 100644 index 0000000..d6cb6cb --- /dev/null +++ b/Project/templates/login.html @@ -0,0 +1,47 @@ + + + + + + 我的航班订票官网 + + + + + +
+

KJF航班订票

+
+
+
+
    + {% for image in images %} +
  • + + + +
  • + {% endfor %} +
+
+
+

尽享精彩出行服务

+ +
+
+
+

© 2024 KJF航班订票. 保留所有权利。

+
+ + + diff --git a/Project/templates/modify.html b/Project/templates/modify.html index dcd57dc..31eae07 100644 --- a/Project/templates/modify.html +++ b/Project/templates/modify.html @@ -1,10 +1,12 @@ - 修改账户 - - - + - - + + + - \ No newline at end of file + diff --git a/Project/templates/signup.html b/Project/templates/signup.html index 518e500..9e920c2 100644 --- a/Project/templates/signup.html +++ b/Project/templates/signup.html @@ -1,115 +1,51 @@ - 我的12306注册 - - - + + + 注册 - KJF航班订票 + + + + - -
-
    -
  • -
    -
    用 户 名:
    - -
    -
  • -
  • -
    -
    登陆密码:
    - - -
    -
  • -
  • -
    -
    确认密码:
    - -
    -
  • -
  • -
    -
    证件类型:
    - - -
    -
  • -
  • -
    -
    姓 名:
    - -
    -
  • -
  • -
    -
    证件号码:
    - -
    -
  • -
  • -
    -
    优惠(待)类型:
    - -
    -
  • -
  • -
  • -
    -
    邮 箱:
    - -
    -
  • -
  • -
    -
    手机号码:
    -
    - - -
    -
    -
  • -
    - -
    -
- -
- - - +
+
    +
  • +
    +
    用户名:
    + +
    {{ errors.username }}
    +
    +
  • +
  • +
    +
    手机号:
    + +
    {{ errors.mobileNo }}
    +
    +
  • +
  • +
    +
    登录密码:
    + + +
    {{ errors.password }}
    +
    +
  • +
  • +
    +
    确认密码:
    + + +
    {{ errors.confirmPassword }}
    +
    +
  • +
    + +
    +
+
- \ No newline at end of file +