调整版本,实现wifi认证

This commit is contained in:
冯佳
2025-07-25 08:08:11 +08:00
parent 97a7d848d4
commit 50f7531518
20 changed files with 5323 additions and 429 deletions

313
main.py
View File

@ -1,5 +1,5 @@
from kivy.properties import ObjectProperty
from kivy.properties import ObjectProperty, StringProperty
from datetime import datetime, timedelta
from kivy.core.text import LabelBase
from kivy.metrics import dp
@ -24,16 +24,21 @@ from kivymd.uix.dialog import MDDialog
from kivymd.uix.label import MDLabel
from kivy.uix.label import Label
from kivy.utils import platform
from kivy.clock import Clock
from kivymd.theming import ThemeManager
LabelBase.register(name="MPoppins", fn_regular="fonts/Chinese/msyh.ttf")
LabelBase.register(name="BPoppins", fn_regular="fonts/Chinese/msyh.ttf")
LabelBase.register(name="RRubik", fn_regular="fonts/Chinese/msyh.ttf")
LabelBase.register(name="RCro", fn_regular="fonts/Chinese/msyh.ttf")
LabelBase.register(name="RPac", fn_regular="fonts/Chinese/msyh.ttf")
def get_books():
pass
class MainScreen(Screen):
pass
@ -41,7 +46,7 @@ class LoginScreen(Screen):
login = ObjectProperty(None)
class SignUpScreen(Screen):
signup: ObjectProperty = ObjectProperty(None)
signup = ObjectProperty(None)
class ForgetPassScreen(Screen):
forget_Password = ObjectProperty(None)
@ -82,7 +87,10 @@ class RenewBookScreen(Screen):
class HistoryScreen(Screen):
history = ObjectProperty(None)
# Window.size = (dp(360), dp(680))
class app(MDApp):
wifi_status_text = StringProperty("")
def __init__(self):
super().__init__()
self.signup_sem = None
@ -140,6 +148,19 @@ class app(MDApp):
self.password = None
self.username = None
self.theme_cls.font_styles["H1"] = ["BPoppins", 96, False, -1.5]
self.theme_cls.font_styles["H2"] = ["BPoppins", 60, False, -0.5]
self.theme_cls.font_styles["H3"] = ["BPoppins", 48, False, 0]
self.theme_cls.font_styles["H4"] = ["BPoppins", 34, False, 0.25]
self.theme_cls.font_styles["H5"] = ["BPoppins", 25, False, 0.15]
self.theme_cls.font_styles["H6"] = ["BPoppins", 16, False, 0.15]
self.theme_cls.font_styles["Subtitle1"] = ["BPoppins", 16, False, 0.15]
self.theme_cls.font_styles["Subtitle2"] = ["BPoppins", 14, False, 0.1]
self.theme_cls.font_styles["Body1"] = ["BPoppins", 16, False, 0.5]
self.theme_cls.font_styles["Body2"] = ["BPoppins", 14, False, 0.25]
self.theme_cls.font_styles["Button"] = ["BPoppins", 14, True, 1.25]
self.theme_cls.font_styles["Caption"] = ["BPoppins", 13, False, 0.15]
self.theme_cls.font_styles["Overline"] = ["BPoppins", 10, True, 1.5]
def build(self):
Builder.load_file('kv/app.kv')
@ -161,115 +182,197 @@ class app(MDApp):
screen_manager.add_widget(RenewBookScreen(name="renew_book"))
screen_manager.add_widget(HistoryScreen(name="history"))
Clock.schedule_once(self.update_wifi_status, 2)
return screen_manager
#############################################ALL INPUT TEXT############################################################
def on_start(self):
# 从根窗口中获取名为"login"的屏幕(登录界面)
login_screen = self.root.get_screen("login")
self.username = login_screen.ids.username
self.password = login_screen.ids.password
# 通过界面ID获取登录界面中的用户名输入框组件
# self.username = login_screen.ids.username
# 通过界面ID获取登录界面中的密码输入框组件
# self.password = login_screen.ids.password
# 从根窗口中获取名为"home"的屏幕(主界面)
home_screen = self.root.get_screen("home")
# 通过界面ID获取主界面中的用户信息组件
self.user = home_screen.ids.user
# 通过界面ID获取主界面中的书架位置名称组件
self.book_pos_name = home_screen.ids.book_pos_name
# 通过界面ID获取主界面中的书架位置组件
self.book_pos = home_screen.ids.book_pos
# 从根窗口中获取名为"forgot_pass"的屏幕(忘记密码界面)
forgot_pass_screen = self.root.get_screen("forgot_pass")
# 通过界面ID获取忘记密码界面中的手机号输入框组件
self.mobile_no = forgot_pass_screen.ids.forgotPass_no
# 从根窗口中获取名为"reset_pass"的屏幕(重置密码界面)
reset_pass_screen = self.root.get_screen("reset_pass")
# 通过界面ID获取重置密码界面中的新密码输入框组件
self.new_pass = reset_pass_screen.ids.new_pass
# 通过界面ID获取重置密码界面中的确认新密码输入框组件
self.new_pass1 = reset_pass_screen.ids.new_pass1
# 从根窗口中获取名为"otp"的屏幕(验证码界面)
otp_screen = self.root.get_screen("otp")
# 通过界面ID获取验证码界面中的"验证"按钮组件
self.otp_button = otp_screen.ids.otp_button
# 通过界面ID获取验证码界面中的"返回"按钮组件
self.back_button = otp_screen.ids.back_button
# 通过界面ID获取验证码界面中的第一个数字输入框组件
self.d1 = otp_screen.ids.d1
# 通过界面ID获取验证码界面中的第二个数字输入框组件
self.d2 = otp_screen.ids.d2
# 通过界面ID获取验证码界面中的第三个数字输入框组件
self.d3 = otp_screen.ids.d3
# 通过界面ID获取验证码界面中的第四个数字输入框组件
self.d4 = otp_screen.ids.d4
# 从根窗口中获取名为"signup"的屏幕(注册界面)
signup_screen = self.root.get_screen("signup")
# 通过界面ID获取注册界面中的用户名输入框组件
self.user_name = signup_screen.ids.signup_name
# 通过界面ID获取注册界面中的PRN可能是学号/身份标识)输入框组件
self.user_prn = signup_screen.ids.signup_prn
# 通过界面ID获取注册界面中的邮箱输入框组件
self.user_email = signup_screen.ids.signup_email
# 通过界面ID获取注册界面中的手机号输入框组件
self.user_no = signup_screen.ids.signup_no
# 通过界面ID获取注册界面中的密码输入框组件
self.user_pass = signup_screen.ids.signup_pass
# 通过界面ID获取注册界面中的所属部门/专业选择组件
self.signup_branch = signup_screen.ids.signup_branch
# 通过界面ID获取注册界面中的年级/学期选择组件
self.signup_sem = signup_screen.ids.signup_sem
# 从根窗口中获取名为"profile"的屏幕(个人资料界面)
profile_screen = self.root.get_screen("profile")
# 通过界面ID获取个人资料界面中的姓名展示组件
self.profile_name = profile_screen.ids.profile_name
# 通过界面ID获取个人资料界面中的邮箱展示组件
self.profile_email = profile_screen.ids.profile_email
# 通过界面ID获取个人资料界面中的PRN身份标识展示组件
self.profile_prn = profile_screen.ids.profile_prn
# 通过界面ID获取个人资料界面中的手机号展示组件
self.profile_number = profile_screen.ids.profile_number
# 通过界面ID获取个人资料界面中的所属部门/专业展示组件
self.profile_branch = profile_screen.ids.profile_branch
# 通过界面ID获取个人资料界面中的年级/学期展示组件
self.profile_semester = profile_screen.ids.profile_semester
# 从根窗口中获取名为"profile_edit"的屏幕(个人资料编辑界面)
self.profile_edit_screen = self.root.get_screen("profile_edit")
# 通过界面ID获取资料编辑界面中的姓名编辑输入框组件
self.edit_name = self.profile_edit_screen.ids.edit_name
# 通过界面ID获取资料编辑界面中的邮箱编辑输入框组件
self.edit_email = self.profile_edit_screen.ids.edit_email
# 通过界面ID获取资料编辑界面中的PRN身份标识编辑输入框组件
self.edit_prn = self.profile_edit_screen.ids.edit_prn
# 通过界面ID获取资料编辑界面中的手机号编辑输入框组件
self.edit_number = self.profile_edit_screen.ids.edit_no
# 通过界面ID获取资料编辑界面中的所属部门/专业编辑选择组件
self.edit_branch = self.profile_edit_screen.ids.edit_branch
# 通过界面ID获取资料编辑界面中的年级/学期编辑选择组件
self.edit_semester = self.profile_edit_screen.ids.edit_sem
# 从根窗口中获取名为"borrow_book"的屏幕(借书界面)
borrow_screen = self.root.get_screen("borrow_book")
# 通过界面ID获取借书界面中的ISBN图书编号输入框组件
self.isbn = borrow_screen.ids.isbn
# 从根窗口中获取名为"return_book"的屏幕(还书界面)
return_book_screen = self.root.get_screen("return_book")
# 通过界面ID获取还书界面中的图片与标签网格布局组件
self.image_label_grid = return_book_screen.ids.image_label_grid
# 从根窗口中获取名为"renew_book"的屏幕(图书续借界面)
renew_book_screen = self.root.get_screen("renew_book")
# 通过界面ID获取续借界面中的网格布局组件
self.renew_grid = renew_book_screen.ids.renew_grid
# 从根窗口中获取名为"history"的屏幕(借阅历史界面)
history_screen = self.root.get_screen("history")
# 通过界面ID获取借阅历史界面中的网格布局组件
self.history_grid = history_screen.ids.history_grid
# 从根窗口中获取名为"searchBook"的屏幕(图书搜索界面)
search_book_screen = self.root.get_screen("searchBook")
# 通过界面ID获取图书搜索界面中的搜索输入框组件
self.search_field = search_book_screen.ids.search_field
# 通过界面ID获取图书搜索界面中的搜索结果网格布局组件
self.search_grid = search_book_screen.ids.search_grid
# 从根窗口中获取名为"recommend"的屏幕(图书推荐界面)
self.recommend_screen = self.root.get_screen("recommend")
# 通过界面ID获取推荐界面中的图书输入框组件
self.book_input = self.recommend_screen.ids.book_input
# 通过界面ID获取推荐界面中的推荐结果网格布局组件
self.rec_grid = self.recommend_screen.ids.rec_grid
# 通过界面ID获取推荐界面中的推荐信息标签组件
self.rec_label = self.recommend_screen.ids.rec_label
#############################################@Frequently used functions##################################################
@staticmethod
def change_cursor(is_enter):
"""改变鼠标指针样式"""
# 如果is_enter为True鼠标进入目标区域将鼠标指针改为手型
if is_enter:
Window.set_system_cursor('hand')
# 否则(鼠标离开目标区域),将鼠标指针改回默认箭头样式
else:
Window.set_system_cursor('arrow')
@staticmethod
def toggle_password_visibility(password_field, icon_button):
"""切换密码输入框的可见性状态"""
# 检查密码输入框当前是否处于密码隐藏状态
if password_field.password:
# 如果是隐藏状态,切换为可见状态
password_field.password = False
# 更新图标为"eye"(眼睛图标,表示当前可见)
icon_button.icon = "eye"
else:
# 如果是可见状态,切换为隐藏状态(显示为圆点/星号)
password_field.password = True
# 更新图标为"eye-off"(闭眼图标,表示当前隐藏)
icon_button.icon = "eye-off"
def clear_text(self):
"""清空界面中所有输入框和文本组件的内容"""
# 清空图书搜索框内容
self.search_field.text = ""
# 清空图书推荐输入框内容
self.book_input.text = ""
self.username.text = ""
self.password.text = ""
# 清空登录界面的用户名输入框内容
# self.username.text = ""
# 清空登录界面的密码输入框内容
# self.password.text = ""
# 清空忘记密码界面的手机号输入框内容
self.mobile_no.text = ""
# 清空验证码界面的第一个输入框内容
self.d1.text = ""
# 清空验证码界面的第二个输入框内容
self.d2.text = ""
# 清空验证码界面的第三个输入框内容
self.d3.text = ""
# 清空验证码界面的第四个输入框内容
self.d4.text = ""
# 清空书架位置名称文本内容
self.book_pos_name.text = ""
self.book_pos.text = "Example.,Book Position is 1L42 , 1 represent row no., L represent left side of row, 4 represent rack/shelves no. ,2 represent shelves step no."
# 重置书架位置说明文本为示例内容
self.book_pos.text = "测试内容示例"
# 再次清空手机号输入框(可能是为了确保完全清空)
self.mobile_no.text = ""
# 清空借书界面的ISBN输入框内容
self.isbn.text = ''
def on_press_back_arrow(self):
self.username.text = ""
self.password.text = ""
# self.username.text = ""
# self.password.text = ""
self.mobile_no.text = ""
self.d1.text = ""
self.d2.text = ""
@ -340,54 +443,154 @@ class app(MDApp):
###################################LoginPageWork-Start#################################################
# login Verification function "verify"
def verify(self, obj):
status = False
if self.username.text == "" or self.password.text == "":
check = "请输入账户和密码"
return self.dialog1(check)
else:
name = ""
with open('data/Users.csv', "r", encoding="utf-8") as file:
csv_reader = csv.reader(file, delimiter=",")
for line in csv_reader:
try:
if not obj:
a = (line[1] == self.username.text or line[2] == self.username.text)
else:
a = (line[1] == self.edit_prn.text or line[2] == self.edit_email.text)
if a and line[4] == self.password.text:
status = True
name = line[0]
prn = line[1]
email = line[2]
number = line[3]
branch = line[5]
semester = line[6]
break
except IndexError:
pass
except Exception as e:
print(e)
# # login Verification function "verify"
# def verify(self, obj):
# status = False
# if self.username.text == "" or self.password.text == "":
# check = "请输入账户和密码"
# return self.dialog1(check)
# else:
# name = ""
# with open('data/Users.csv', "r", encoding="utf-8") as file:
# csv_reader = csv.reader(file, delimiter=",")
# for line in csv_reader:
# try:
# if not obj:
# a = (line[1] == self.username.text or line[2] == self.username.text)
# else:
# a = (line[1] == self.edit_prn.text or line[2] == self.edit_email.text)
# if a and line[4] == self.password.text:
# status = True
# name = line[0]
# prn = line[1]
# email = line[2]
# number = line[3]
# branch = line[5]
# semester = line[6]
# break
# except IndexError:
# pass
# except Exception as e:
# print(e)
if status:
if not obj:
check = "Login Successful" + "\nHello! " + name
else:
check = "Profile Updated Successfully!"
self.secure_profile()
self.root.current = "home"
self.user.text = f"""[b]Hey! {name}[/b]"""
self.profile_name.text = self.edit_name.text = name
self.profile_email.text = self.edit_email.text = email
self.profile_prn.text = self.edit_prn.text = prn
self.profile_number.text = self.edit_number.text = number
self.profile_semester.text = self.edit_semester.text = semester
self.profile_branch.text = self.edit_branch.text = branch
# if status:
# if not obj:
# check = "Login Successful" + "\nHello! " + name
# else:
# check = "Profile Updated Successfully!"
# self.secure_profile()
# self.root.current = "home"
# self.user.text = f"""[b]Hey! {name}[/b]"""
# self.profile_name.text = self.edit_name.text = name
# self.profile_email.text = self.edit_email.text = email
# self.profile_prn.text = self.edit_prn.text = prn
# self.profile_number.text = self.edit_number.text = number
# self.profile_semester.text = self.edit_semester.text = semester
# self.profile_branch.text = self.edit_branch.text = branch
# else:
# check = "Login Failed!. " + "Enter correct username and password."
# self.dialog1(check)
def update_wifi_status(self, dt):
self.check_wifi()
Clock.schedule_once(self.update_wifi_status, 1) # 5秒刷新一次
def check_wifi(self):
if platform != 'android':
self.wifi_status_text = '非Android设备'
return
try:
from jnius import autoclass, cast
PythonActivity = autoclass('org.kivy.android.PythonActivity')
Context = autoclass('android.content.Context')
activity = PythonActivity.mActivity
WifiManager = autoclass('android.net.wifi.WifiManager')
Formatter = autoclass('android.text.format.Formatter')
wifi_service = activity.getSystemService(Context.WIFI_SERVICE)
wifi_manager = cast('android.net.wifi.WifiManager', wifi_service)
if not wifi_manager.isWifiEnabled():
self.wifi_status_text = 'WiFi 未启用'
return # 这里直接返回不再继续取SSID等信息
wifi_info = wifi_manager.getConnectionInfo()
if wifi_info is None:
self.wifi_status_text = 'WiFi 信息不可用'
return
ssid = wifi_info.getSSID()
if ssid:
ssid_display = ssid.strip('"')
else:
check = "Login Failed!. " + "Enter correct username and password."
self.dialog1(check)
ssid_display = "SSID Unknown"
ip_int = wifi_info.getIpAddress()
ip_str = Formatter.formatIpAddress(ip_int) if ip_int != 0 else "0.0.0.0"
link_speed = wifi_info.getLinkSpeed() # Mbps
bssid = wifi_info.getBSSID()
rssi = wifi_info.getRssi()
self.wifi_status_text = (
f'SSID: {ssid_display}\n'
f'IP: {ip_str}\n'
f'速度: {link_speed} Mbps\n'
f'BSSID: {bssid}\n'
f'信号: {rssi} dBm'
)
except Exception as e:
self.wifi_status_text = f'获取WiFi信息失败\n{e}'
def verify(self, obj=None):
try:
if platform == "android":
from jnius import autoclass
PythonActivity = autoclass('org.kivy.android.PythonActivity')
Context = autoclass('android.content.Context')
activity = PythonActivity.mActivity
wifi_service = activity.getSystemService(Context.WIFI_SERVICE)
wifi_info = wifi_service.getConnectionInfo()
wifi_id = wifi_info.getSSID().strip('"').lower()
else:
wifi_id = "zhizhan-2" # 非 Android 用模拟 WiFi
except Exception as e:
self.dialog1(f"获取WiFi信息失败{e}")
return
try:
with open("data/Users.csv", "r", encoding="utf-8") as file:
csv_reader = csv.reader(file)
for line in csv_reader:
# 确保至少有7列数据
if len(line) < 7:
continue
csv_ssid = line[7].strip().lower() if len(line) > 7 else ""
if wifi_id == csv_ssid or wifi_id in map(str.lower, line):
name, prn, email, number, password, branch, semester = line[:7]
self.root.current = "home"
self.user.text = f"[b]Hey! {name}[/b]"
self.profile_name.text = self.edit_name.text = name
self.profile_email.text = self.edit_email.text = email
self.profile_prn.text = self.edit_prn.text = prn
self.profile_number.text = self.edit_number.text = number
self.profile_semester.text = self.edit_semester.text = semester
self.profile_branch.text = self.edit_branch.text = branch
self.dialog1(f"欢迎你,{name} wifi认证成功")
return
except Exception as e:
self.dialog1(f"读取用户信息失败:{e}")
return
self.dialog1("当前WiFi认证失败,请检查网络或退出")
click_count = 0
def login_mode(self, username_text, button_text):