Browse Source

feat: 界面显示

SongZihuan 3 years ago
parent
commit
b62e1cb891
4 changed files with 174 additions and 25 deletions
  1. 5 4
      control/__init__.py
  2. 155 11
      control/tk.py
  3. 12 8
      core/user.py
  4. 2 2
      sql/garbage.py

+ 5 - 4
control/__init__.py

@@ -63,14 +63,15 @@ class Control:
         self._user_last_time: time_t = 0
 
     def check_user(self):
-        if time.time() - self._user_last_time > 20:
-            self._user = None
         if self._user is None:
             return False
+        if not self._user.is_manager() and time.time() - self._user_last_time > 20:
+            self._user = None
+            return False
         return True
 
     def __check_user(self):
-        if self.check_user():
+        if not self.check_user():
             raise ControlNotLogin
         self._user_last_time = time.time()
 
@@ -129,7 +130,7 @@ class Control:
         """
         if self._user is not None and self._user.get_uid() == user.get_uid() and self.check_user():  # 正在登陆期
             self._user = None  # 退出登录
-            self._user_last_time = None
+            self._user_last_time = 0
             return False
         self._user = user
         self._user_last_time = time.time()

+ 155 - 11
control/tk.py

@@ -1,5 +1,5 @@
 import PIL.Image
-
+import time
 import conf
 import cv2
 import tkinter as tk
@@ -7,12 +7,102 @@ import tkinter.font as font
 from tool.type_ import *
 import datetime
 from PIL import Image, ImageTk
-from control import Control, global_control, ControlScanType, ControlNotLogin
+from control import Control, global_control, ControlScanType, ControlNotLogin, ThrowGarbageError, CheckGarbageError
+from core.user import User, UserNotSupportError
+from core.garbage import GarbageBag, GarbageType, GarbageBagNotUse
+import tkinter.messagebox as msg
+
+
+class GarbageStationException(Exception):
+    ...
+
+
+class GarbageStationStatus:
+    status_normal = 1
+    status_get_garbage_type = 2
+    status_get_garbage_check = 3
+
+    def __init__(self, win, ctrl: Control = global_control):
+        self._win: GarbageStation = win
+        self._ctrl = ctrl
+        self._garbage: Optional[GarbageBag] = None
+        self._flat = GarbageStationStatus.status_normal
+
+    def to_get_garbage_type(self, garbage: GarbageBag):
+        self._flat = GarbageStationStatus.status_get_garbage_type
+        self.set_garbage(garbage)
+
+    def to_get_garbage_check(self, garbage: GarbageBag):
+        self._flat = GarbageStationStatus.status_get_garbage_check
+        self.set_garbage(garbage)
+
+    def set_garbage(self, garbage: GarbageBag):
+        self._garbage = garbage
+
+    def get_garbage(self) -> Optional[GarbageBag]:
+        if not self._ctrl.check_user():
+            self._garbage = None
+        return self._garbage
+
+    def get_user_info_no_update(self):
+        return self._ctrl.get_user_info_no_update()
+
+    def scan(self):
+        return self._ctrl.scan()
+
+    def get_cap_img(self):
+        return self._ctrl.get_cap_img()
+
+    def switch_user(self, user: User):
+        return self._ctrl.switch_user(user)
+
+    def throw_garbage(self, garbage_type: enum):
+        if self._flat != GarbageStationStatus.status_get_garbage_type or self._garbage is None:
+            msg.showwarning("Operation Fail", "You should login first and scan the QR code of the trash bag")
+            return
+
+        try:
+            self._ctrl.throw_garbage(self._garbage, garbage_type)
+        except (ThrowGarbageError, UserNotSupportError, ControlNotLogin):
+            msg.showwarning("Operation Fail", "The garbage bags have been used.")
+            raise
+        finally:
+            self._flat = GarbageStationStatus.status_normal
+            self._garbage = None
+
+    def check_garbage(self, check: bool):
+        if self._flat != GarbageStationStatus.status_get_garbage_check or self._garbage is None:
+            msg.showwarning("Operation Fail", "You should login first and scan the QR code of the trash bag")
+            return
+
+        try:
+            self._ctrl.check_garbage(self._garbage, check)
+        except (ThrowGarbageError, UserNotSupportError, CheckGarbageError, GarbageBagNotUse):
+            msg.showwarning("Operation Fail", "The garbage bag has been checked")
+        finally:
+            self._flat = GarbageStationStatus.status_normal
+            self._garbage = None
+
+    def show_garbage_info(self):
+        if self._flat != GarbageStationStatus.status_get_garbage_check or self._garbage is None:
+            msg.showwarning("Operation Fail", "You should login first and scan the QR code of the trash bag")
+            return
+
+        if not self._garbage.is_use():
+            msg.showwarning("Operation Fail", "The garbage bag has not been used")
+            return
+
+        info = self._garbage.get_info()
+        garbage_type = GarbageType.GarbageTypeStrList[int(info['type'])]
+        time_str = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(float(info['use_time'])))
+        msg.showwarning("Garbage Info", f"type = {garbage_type}\n"
+                                        f"location = {info['loc']}\n"
+                                        f"use-time = {time_str}")
 
 
 class GarbageStation:
     def __init__(self, ctrl: Control = global_control):
-        self._ctrl = ctrl
+        self._status = GarbageStationStatus(self, ctrl)
         self._window = tk.Tk()
         self._sys_height = self._window.winfo_screenheight()
         self._sys_width = self._window.winfo_screenwidth()
@@ -75,6 +165,7 @@ class GarbageStation:
                                            tk.Button(self._user_btn_frame)]
         self.__conf_user_btn()
         self.__conf_after()
+        self.all_user_disable()
 
     def __conf_windows(self):
         self._window.title('HGSSystem: Garbage Station')
@@ -180,6 +271,11 @@ class GarbageStation:
             btn['bg'] = info[1]
             btn['text'] = info[0]
 
+        self._throw_ctrl_btn[0]['command'] = lambda: self._status.throw_garbage(GarbageType.recyclable)
+        self._throw_ctrl_btn[1]['command'] = lambda: self._status.throw_garbage(GarbageType.other)
+        self._throw_ctrl_btn[2]['command'] = lambda: self._status.throw_garbage(GarbageType.hazardous)
+        self._throw_ctrl_btn[3]['command'] = lambda: self._status.throw_garbage(GarbageType.kitchen)
+
         self._throw_ctrl_btn[0].place(relx=0.000, rely=0.000, relwidth=0.495, relheight=0.495)
         self._throw_ctrl_btn[1].place(relx=0.505, rely=0.000, relwidth=0.495, relheight=0.495)
         self._throw_ctrl_btn[2].place(relx=0.000, rely=0.505, relwidth=0.495, relheight=0.495)
@@ -196,7 +292,9 @@ class GarbageStation:
             btn['font'] = btn_font
             btn['text'] = info[0]
             btn['bg'] = info[1]
-            btn['state'] = 'disabled'
+
+        self._check_ctrl_btn[0]['command'] = lambda: self._status.check_garbage(False)
+        self._check_ctrl_btn[1]['command'] = lambda: self._status.check_garbage(True)
 
         self._check_ctrl_btn[0].place(relx=0.000, rely=0.000, relwidth=0.495, relheight=1)
         self._check_ctrl_btn[1].place(relx=0.505, rely=0.000, relwidth=0.495, relheight=1)
@@ -282,19 +380,26 @@ class GarbageStation:
         rubbish: tk.Variable = self._user_rubbish[2]
         eval_: tk.Variable = self._user_eval[2]
 
-        user_info: Dict[str, str] = self._ctrl.get_user_info_no_update()
+        user_info: Dict[str, str] = self._status.get_user_info_no_update()
         if user_info.get('uid') is None:
             name.set('Not-Login')
             uid.set('Not-Login')
             eval_.set('---')
             rubbish.set('---')
             score.set('---')
-        elif user_info.get('manager', False):
+            self.all_user_disable()
+        elif user_info.get('manager', '0') == '1':
             name.set(user_info.get('name'))
-            uid.set(user_info.get('uid'))
+            uid_get = user_info.get('uid', None)
+            if uid_get is None or len(uid_get) < 32:
+                uid.set('error')
+            else:
+                uid.set(uid_get[0:21])
             eval_.set('Manager-User')
             rubbish.set('Manager-User')
             score.set('Manager-User')
+            self.manager_user_able()
+            self.manager_user_disable()
         else:
             name.set(user_info.get('name'))
             uid_get = user_info.get('uid', None)
@@ -305,6 +410,17 @@ class GarbageStation:
             eval_.set(user_info.get('reputation'))
             rubbish.set(user_info.get('rubbish'))
             score.set(user_info.get('score'))
+            self.normal_user_able()
+            self.normal_user_disable()
+
+        garbage = self._status.get_garbage()
+        if garbage is None:
+            self._garbage_id[2].set('---')
+        else:
+            gid = garbage.get_gid()
+            if len(gid) > 20:
+                gid = gid[-20:]
+            self._garbage_id[2].set(gid)
 
         if update:
             self.__define_after(10, self.update_control)
@@ -312,22 +428,50 @@ class GarbageStation:
     def update_scan(self):
         res: Tuple[enum, any] = ControlScanType.no_to_done, None
         try:
-            res = self._ctrl.scan()
+            res = self._status.scan()
         except ControlNotLogin:
-            ...
+            msg.showwarning("Scan Fail", "You should login first.")
 
         # 需要存储一些数据 谨防被gc释放
-        _cap_img_info = (Image.fromarray(cv2.cvtColor(self._ctrl.get_cap_img(), cv2.COLOR_BGR2RGB)).
+        _cap_img_info = (Image.fromarray(cv2.cvtColor(self._status.get_cap_img(), cv2.COLOR_BGR2RGB)).
                          transpose(Image.FLIP_LEFT_RIGHT))
         self._cap_img = ImageTk.PhotoImage(image=_cap_img_info)
         self._cap_label['image'] = self._cap_img
 
         if res[0] == ControlScanType.switch_user:
-            self._ctrl.switch_user(res[1])
+            self._status.switch_user(res[1])
+            self.update_control(False)
+        elif res[0] == ControlScanType.throw_garbage:
+            self._status.to_get_garbage_type(res[1])
+            self.update_control(False)
+        elif res[0] == ControlScanType.check_garbage:
+            self._status.to_get_garbage_check(res[1])
             self.update_control(False)
 
         self.__define_after(10, self.update_scan)
 
+    def normal_user_disable(self):
+        for btn in self._check_ctrl_btn:
+            btn['state'] = 'disabled'
+        self._user_btn[0]['command'] = lambda: None
+
+    def manager_user_disable(self):
+        for btn in self._throw_ctrl_btn:
+            btn['state'] = 'disabled'
+        self._user_btn[0]['command'] = lambda: self._status.show_garbage_info()
+
+    def all_user_disable(self):
+        self.manager_user_disable()
+        self.normal_user_disable()
+
+    def normal_user_able(self):
+        for btn in self._throw_ctrl_btn:
+            btn['state'] = 'normal'
+
+    def manager_user_able(self):
+        for btn in self._check_ctrl_btn:
+            btn['state'] = 'normal'
+
     @staticmethod
     def __make_font(family: str = 'noto', **kwargs):
         return font.Font(family=conf.font_d[family], **kwargs)

+ 12 - 8
core/user.py

@@ -47,11 +47,7 @@ class User(metaclass=abc.ABCMeta):
         return self._type
 
     def get_info(self) -> Dict[str, str]:
-        return {
-            "name": str(self._name),
-            "uid": str(self._uid),
-            "manager": self._type == UserType.manager if '1' else '0'
-        }
+        raise UserNotSupportError
 
     def __repr__(self):
         tmp = UserType.UserTypeStrList
@@ -92,7 +88,7 @@ class NormalUser(User):
         return {
             "name": str(self._name),
             "uid": str(self._uid),
-            "manager": self._type == UserType.manager if '1' else '0',
+            "manager": '0',
             "reputation": str(self._reputation),
             "rubbish": str(self._rubbish),
             "score": str(self._score)
@@ -172,7 +168,7 @@ class NormalUser(User):
         elif self._rubbish > conf.limit_rubbish_week:
             raise UserRubbishException
 
-        if garbage.is_use() or not garbage.is_check():
+        if garbage.is_use() or garbage.is_check()[0]:
             return False
         garbage.config_use(garbage_type, HGSTime(), self._uid, loc)
 
@@ -188,8 +184,9 @@ class ManagerUser(User):
         super(ManagerUser, self).__init__(name, uid, UserType.manager)
 
     def check_rubbish(self, garbage: GarbageBag, right: bool, user: User) -> bool:
-        if not garbage.is_use() or garbage.is_check() or user.get_uid() != garbage.get_user():
+        if (not garbage.is_use()) or garbage.is_check()[0] or user.get_uid() != garbage.get_user():
             return False
+
         garbage.config_check(right, self._uid)
         user.evaluate(right)
 
@@ -207,3 +204,10 @@ class ManagerUser(User):
             ...
 
         return True
+
+    def get_info(self) -> Dict[str, str]:
+        return {
+            "name": str(self._name),
+            "uid": str(self._uid),
+            "manager": '1'
+        }

+ 2 - 2
sql/garbage.py

@@ -100,10 +100,10 @@ def update_garbage(garbage: GarbageBag, db: DB) -> bool:
     if re is None:
         return False
 
-    if re.is_use() and not garbage.is_use() or re.is_check() and not garbage.is_check():
+    if re.is_use() and not garbage.is_use() or re.is_check()[0] and not garbage.is_check():
         return False
 
-    if not garbage.is_use() and not garbage.is_check():
+    if not garbage.is_use() and not garbage.is_check()[0]:
         return True  # 不做任何修改
 
     gid = garbage.get_gid()