Browse Source

feat: 去除不必要的字面量

SongZihuan 3 years ago
parent
commit
8214041301
10 changed files with 476 additions and 291 deletions
  1. 0 240
      control/__init__.py
  2. 208 0
      control/ranking.py
  3. 250 38
      control/station.py
  4. 0 1
      core/user.py
  5. 4 3
      equipment/scan.py
  6. 5 2
      equipment/scan_garbage.py
  7. 5 2
      equipment/scan_user.py
  8. 0 3
      sql/db.py
  9. 2 1
      sql/garbage.py
  10. 2 1
      sql/user.py

+ 0 - 240
control/__init__.py

@@ -1,240 +0,0 @@
-import conf
-import time
-from tool.type_ import *
-from sql.db import DB, mysql_db
-from sql.user import update_user, find_user_by_id, creat_new_user
-from sql.garbage import update_garbage, creat_new_garbage
-from equipment.scan import HGSCapture, HGSQRCoder, QRCode, capture, qr_capture
-from equipment.scan_user import scan_user, write_uid_qr, write_all_uid_qr
-from equipment.scan_garbage import scan_garbage, write_gid_qr
-from core.user import User, UserNotSupportError
-from core.garbage import GarbageBag, GarbageType, GarbageBagNotUse
-
-
-class ControlError(Exception):
-    ...
-
-
-class ControlNotLogin(ControlError):
-    ...
-
-
-class ThrowGarbageError(ControlError):
-    ...
-
-
-class CheckGarbageError(ControlError):
-    ...
-
-
-class CreatGarbageError(ControlError):
-    ...
-
-
-class CreatUserError(ControlError):
-    ...
-
-
-class RankingUserError(ControlError):
-    ...
-
-
-class ControlScanType:
-    switch_user = 1
-    throw_garbage = 2
-    check_garbage = 3
-    no_to_done = 4
-
-
-class Control:
-    __control = None
-
-    def __new__(cls, *args, **kwargs):
-        if cls.__control is None:
-            cls.__control = super(Control, cls).__new__(cls, *args, **kwargs)
-        return cls.__control
-
-    def __init__(self,
-                 db: DB = mysql_db,
-                 cap: HGSCapture = capture,
-                 qr: HGSQRCoder = qr_capture,
-                 loc: location_t = conf.base_location):
-        self._db: DB = db
-        self._cap = cap
-        self._qr = qr
-        self._loc: location_t = loc
-        self._user: Optional[User] = None  # 操作者
-        self._user_last_time: time_t = 0
-
-    def update_user_time(self):
-        if self.check_user():
-            self._user_last_time = time.time()
-
-    def is_manager(self):
-        if not self.check_user():
-            return False
-        return self._user.is_manager()
-
-    def check_user(self):
-        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 not self.check_user():
-            raise ControlNotLogin
-        self._user_last_time = time.time()
-
-    def __check_normal_user(self):
-        self.__check_user()
-        if self._user.is_manager():
-            raise UserNotSupportError
-
-    def __check_manager_user(self):
-        self.__check_user()
-        if not self._user.is_manager():
-            raise UserNotSupportError
-
-    def get_user_info(self):
-        self.__check_user()
-        return self._user.get_info()
-
-    def get_uid_no_update(self):
-        if not self.check_user():
-            return ""
-        return self._user.get_uid()
-
-    def get_user_info_no_update(self) -> Dict[str, str]:
-        if not self.check_user():
-            return {}
-        return self._user.get_info()
-
-    def scan(self) -> Tuple[int, any]:
-        """
-        处理扫码事务
-        二维码扫描的任务包括: 登录, 扔垃圾, 标记垃圾
-        :return:
-        """
-        self._cap.get_image()
-        qr_code = self._qr.get_qr_code()
-        if qr_code is None:
-            return ControlScanType.no_to_done, None
-
-        user: Optional[User] = scan_user(qr_code, self._db)
-        if user is not None:
-            return ControlScanType.switch_user, user
-
-        garbage: Optional[GarbageBag] = scan_garbage(qr_code, self._db)
-        if garbage is not None:
-            if self._user is None:
-                raise ControlNotLogin
-            if self._user.is_manager():
-                return ControlScanType.check_garbage, garbage
-            return ControlScanType.throw_garbage, garbage
-
-        return ControlScanType.no_to_done, None
-
-    def get_cap_img(self):
-        return self._cap.get_frame()
-
-    def switch_user(self, user: User) -> bool:
-        """
-        切换用户: 退出/登录
-        :param user: 新用户
-        :return: 登录-True, 退出-False
-        """
-        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 = 0
-            return False
-        self._user = user
-        self._user_last_time = time.time()
-        return True  # 登录
-
-    def throw_garbage(self, garbage: GarbageBag, garbage_type: enum):
-        self.__check_normal_user()
-        if not self._user.throw_rubbish(garbage, garbage_type, self._loc):
-            raise ThrowGarbageError
-        update_garbage(garbage, self._db)
-        update_user(self._user, self._db)
-
-    def check_garbage(self, garbage: GarbageBag, check_result: bool):
-        self.__check_manager_user()
-        user = find_user_by_id(garbage.get_user(), self._db)
-        if user is None:
-            raise GarbageBagNotUse
-        if not self._user.check_rubbish(garbage, check_result, user):
-            raise CheckGarbageError
-        update_garbage(garbage, self._db)
-        update_user(self._user, self._db)
-        update_user(user, self._db)
-
-    def creat_garbage(self, path: str, num: int = 1) -> List[tuple[str, Optional[GarbageBag]]]:
-        self.__check_manager_user()
-        if self._user is None:
-            raise ControlNotLogin
-
-        re = []
-        for _ in range(num):
-            gar = creat_new_garbage(self._db)
-            if gar is None:
-                raise CreatGarbageError
-            res = write_gid_qr(gar.get_gid(), path, self._db)
-            re.append(res)
-        return re
-
-    def creat_user(self, name: uname_t, passwd: passwd_t, phone: str, manager: bool) -> Optional[User]:
-        user = creat_new_user(name, passwd, phone, manager, self._db)
-        if user is None:
-            raise CreatUserError
-        return user
-
-    def creat_user_from_list(self, user_list: List[Tuple[uname_t, passwd_t, str]], manager: bool) -> List[User]:
-        re = []
-        for i in user_list:
-            user = creat_new_user(i[0], i[1], i[2], manager, self._db)
-            if user is None:
-                raise CreatUserError
-            re.append(user)
-        return re
-
-    def get_uid_qrcode(self, uid: uid_t, path: str) -> Tuple[str, Optional[User]]:
-        return write_uid_qr(uid, path, self._db)
-
-    def get_uid_qrcode_from_list(self, uid_list: List[uid_t], path: str) -> List[Tuple[str, Optional[User]]]:
-        re = []
-        for uid in uid_list:
-            res = write_uid_qr(uid, path, self._db)
-            re.append(res)
-        return re
-
-    def get_all_uid_qrcode(self, path: str, where: str = "") -> List[str]:
-        return write_all_uid_qr(path, self._db, where=where)
-
-    def ranking(self, limit: int = 0, order_by: str = 'DESC') -> list[Tuple[uid_t, uname_t, score_t, score_t]]:
-        """
-        获取排行榜的功能
-        :return:
-        """
-        if limit > 0:
-            limit = f"LIMIT {int(limit)}"
-        else:
-            limit = ""
-
-        if order_by != 'ASC' and order_by != 'DESC':
-            order_by = 'DESC'
-
-        cur = self._db.search((f"SELECT uid, name, score, reputation "
-                               f"FROM user "
-                               f"WHERE manager = 0 "
-                               f"ORDER BY reputation {order_by}, score {order_by} "
-                               f"{limit}"))
-        if cur is None:
-            raise RankingUserError
-        return list(cur.fetchall())
-
-
-global_control = Control()

+ 208 - 0
control/ranking.py

@@ -0,0 +1,208 @@
+import conf
+import tkinter as tk
+import tkinter.font as font
+from tool.type_ import *
+
+
+class RankingStationException(Exception):
+    ...
+
+
+class RankingStatus:
+    status_normal = 1
+    status_get_garbage_type = 2
+    status_get_garbage_check = 3
+
+    def __init__(self, win):
+        self._win: RankingStation = win
+        self.rank = [[]]
+        self.rank_index = 0
+
+    def get_show_rank(self):
+        rank_list = self.ranking()
+        self.rank = [[]]
+        for i, r in enumerate(rank_list):
+            if len(self.rank[-1]) == 5:
+                self.rank.append([])
+            color = None
+            if i == 0:
+                color = "#eaff56"
+            elif i == 1:
+                color = "#ffa631"
+            elif i == 2:
+                color = "#ff7500"
+            self.rank[-1].append((i + 1, r[1], r[0], r[2], r[3], color))
+
+        self.rank_index = 0
+        self.show_rank(0)
+
+    def show_rank(self, n: int):
+        self.update_user_time()
+        self.rank_index += n
+
+        if self.rank_index < 0 or self.rank_index >= len(self.rank):
+            return
+
+        self._win.show_rank(self.rank_index + 1, len(self.rank),
+                            lambda: self.show_rank(-1),
+                            lambda: self.show_rank(+1),
+                            self.rank[self.rank_index])
+
+
+class RankingStation:
+    def __init__(self, refresh_delay: int = conf.tk_refresh_delay):
+        self.refresh_delay = refresh_delay
+        self._status = RankingStatus(self)
+
+        self._window = tk.Tk()
+        self._sys_height = self._window.winfo_screenheight()
+        self._sys_width = self._window.winfo_screenwidth()
+
+        self._win_height = int(self._sys_height * (2 / 3))
+        self._win_width = int(self._sys_width * (1 / 3))
+        self._full_screen = False
+        self.__conf_windows()
+
+        self.__conf_font_size()
+        self.__creat_tk()
+        self.__conf_tk()
+
+    def __creat_tk(self):
+        self._rank_frame = tk.Frame(self._window)
+        self._rank_title = tk.Label(self._rank_frame)
+        self._rank_title_var = tk.StringVar()
+        self._rank_count = 7
+        self._rank_label = [tk.Label(self._rank_frame) for _ in range(self._rank_count)]
+        self._rank_y_height: List[Tuple[float, float]] = []  # rank 标签的y坐标信息
+        self._rank_var = [tk.StringVar() for _ in range(self._rank_count)]
+        self._rank_btn = [tk.Button(self._rank_frame) for _ in range(3)]  # prev, auto, next
+
+    def __conf_font_size(self, n: Union[int, float] = 1):
+        self._rank_font_title_size = int(24 * n)
+        self._rank_font_size = int(16 * n)
+        self._rank_font_btn_size = int(20 * n)
+
+    def __conf_tk(self):
+        self.__conf_rank()
+
+    def __conf_windows(self):
+        self._window.title('HGSSystem: Ranking')
+        self._window.geometry(f'{self._win_width}x{self._win_height}')
+        self._window['bg'] = "#F0FFF0"  # 蜜瓜绿
+        self._window.resizable(False, False)
+
+    def __conf_rank(self):
+        title_font = self.__make_font(size=self._rank_font_title_size, weight="bold")
+        info_font = self.__make_font(size=self._rank_font_size)
+        btn_font = self.__make_font(size=self._rank_font_btn_size)
+
+        height = self._win_height * 0.95
+        width = height * (3 / 4)
+
+        # 宽度过大
+        if width >= self._win_width:
+            width = self._win_width * 0.95
+            height = width * (4 / 3) / self._win_width
+
+        relwidth = width / self._win_width
+        relheight = height / self._win_height
+        relx = (1 - relwidth) / 2
+        rely = (1 - relheight) / 2
+
+        self._rank_frame['relief'] = "ridge"
+        self._rank_frame['bd'] = 5
+        self._rank_frame['bg'] = "#F5F5DC"
+        self._rank_frame.place(relx=relx, rely=rely, relwidth=relwidth, relheight=relheight)
+
+        self._rank_title['font'] = title_font
+        self._rank_title['bg'] = "#F5F5DC"
+        self._rank_title['textvariable'] = self._rank_title_var
+        self._rank_title.place(relx=0.02, rely=0.00, relwidth=0.96, relheight=0.1)
+        self._rank_title_var.set("Ranking.loading...")
+
+        """
+        标签所拥有的总高度为0.82
+        标签数为c
+        间隔数为c-1
+        标签高度为x
+        间隔高度为y
+        规定 5y = x
+        所以: cx + (c - 1)y = 0.82
+        得到: 5cx + (c - 1)y = (5c + c - 1)y = 0.82
+        因此: x = 0.82 / (5c + c - 1)
+        """
+
+        height_s = (0.82 / (self._rank_count * 6 - 1))  # 标签的高度
+        height_l = height_s * 5  # 间隔的高度
+
+        height = 0.10  # 从 0.10 到 0.82
+        for i in range(self._rank_count):
+            self._rank_label[i]['font'] = info_font
+            self._rank_label[i]['bg'] = "#F5FFFA"
+            self._rank_label[i]['textvariable'] = self._rank_var[i]
+            self._rank_label[i]['relief'] = "ridge"
+            self._rank_label[i]['bd'] = 2
+            self._rank_var[i].set("")
+            self._rank_y_height.append((height, height_l))
+            height += height_l + height_s
+
+        for btn, text, x in zip(self._rank_btn, ("prev", "close", "next"), (0.050, 0.375, 0.700)):
+            btn['font'] = btn_font
+            btn['text'] = text
+            btn['bg'] = "#00CED1"
+            btn['state'] = "disable"
+            btn.place(relx=x, rely=0.93, relwidth=0.25, relheight=0.06)
+        self.show_rank()
+
+    # def set_rank_info(self, page, page_c, prev_func: Callable, next_func: Callable,
+    #                   rank_info: List[Tuple[int, uname_t, uid_t, score_t, score_t, Optional[str]]]):
+    #     if len(rank_info) > 5:
+    #         rank_info = rank_info[:5]
+    #
+    #     for lb in self._rank_label[1:]:  # 隐藏全部标签
+    #         lb.place_forget()
+    #
+    #     height = 0.12
+    #     for i, info in enumerate(rank_info):
+    #         no, name, uid, score, eval_, color = info
+    #         self._rank_var[i + 1].set(f"NO.{no}  {name}\nUID: {uid[0:conf.ranking_tk_show_uid_len]}\n"
+    #                                   f"Score: {score} Reputation: {eval_}")
+    #         if color is None:
+    #             self._rank_label[i + 1]['bg'] = "#F5FFFA"
+    #         else:
+    #             self._rank_label[i + 1]['bg'] = color
+    #
+    #         self._rank_label[i + 1].place(relx=0.04, rely=height, relwidth=0.92, relheight=0.13)
+    #         height += 0.15
+    #
+    #     self._rank_btn[0]['command'] = prev_func
+    #     self._rank_btn[0]['state'] = 'normal'
+    #     self._rank_btn[1]['command'] = lambda: self.hide_msg_rank(True)
+    #     self._rank_btn[2]['command'] = next_func
+    #     self._rank_btn[2]['state'] = 'normal'
+    #
+    #     if page == 1:
+    #         self._rank_btn[0]['state'] = 'disable'
+    #     if page == page_c:
+    #         self._rank_btn[2]['state'] = 'disable'
+
+    def show_rank(self, *args):
+        for i in range(self._rank_count):
+            rely = self._rank_y_height[i][0]
+            relheight = self._rank_y_height[i][1]
+            self._rank_label[i].place(relx=0.04, rely=rely, relwidth=0.92, relheight=relheight)
+
+    @staticmethod
+    def __make_font(family: str = 'noto', **kwargs):
+        return font.Font(family=conf.font_d[family], **kwargs)
+
+    def mainloop(self):
+        self._window.mainloop()
+
+    def exit_win(self):
+        self._window.destroy()
+
+
+if __name__ == '__main__':
+    station = RankingStation()
+    station.mainloop()

+ 250 - 38
control/tk.py → control/station.py

@@ -2,36 +2,258 @@ import time
 import conf
 import cv2
 import sys
+import random
 import traceback
 import tkinter as tk
 import tkinter.font as font
-from tool.type_ import *
 import datetime
 from PIL import Image, ImageTk
-from control import Control, global_control, ControlScanType, ControlNotLogin, ThrowGarbageError, CheckGarbageError
+
+from tool.type_ import *
+
 from core.user import User, UserNotSupportError
 from core.garbage import GarbageBag, GarbageType, GarbageBagNotUse
-import random
+
+from sql.db import DB
+from sql.user import update_user, find_user_by_id, creat_new_user
+from sql.garbage import update_garbage, creat_new_garbage
+
+from equipment.scan import HGSCapture, HGSQRCoder, QRCode
+from equipment.scan_user import scan_user, write_uid_qr, write_all_uid_qr
+from equipment.scan_garbage import scan_garbage, write_gid_qr
 
 
 class GarbageStationException(Exception):
     ...
 
 
+class ControlNotLogin(GarbageStationException):
+    ...
+
+
+class ThrowGarbageError(GarbageStationException):
+    ...
+
+
+class CheckGarbageError(GarbageStationException):
+    ...
+
+
+class CreatGarbageError(GarbageStationException):
+    ...
+
+
+class CreatUserError(GarbageStationException):
+    ...
+
+
+class RankingUserError(GarbageStationException):
+    ...
+
+
 class GarbageStationStatus:
     status_normal = 1
     status_get_garbage_type = 2
     status_get_garbage_check = 3
 
-    def __init__(self, win, ctrl: Control = global_control):
+    scan_switch_user = 1
+    scan_throw_garbage = 2
+    scan_check_garbage = 3
+    scan_no_to_done = 4
+
+    def __init__(self,
+                 win,
+                 db: DB,
+                 cap: HGSCapture,
+                 qr: HGSQRCoder,
+                 loc: location_t = conf.base_location):
+        self._db: DB = db
+        self._cap = cap
+        self._qr = qr
         self._win: GarbageStation = win
-        self._ctrl = ctrl
+        self._loc: location_t = loc
+
+        self._user: Optional[User] = None  # 操作者
+        self._user_last_time: time_t = 0
+
         self._garbage: Optional[GarbageBag] = None
+
         self._flat = GarbageStationStatus.status_normal
         self._have_easter_eggs = False
+
         self.rank = None
         self.rank_index = 0
 
+    def update_user_time(self):
+        if self.check_user():
+            self._user_last_time = time.time()
+
+    def is_manager(self):
+        if not self.check_user():
+            return False
+        return self._user.is_manager()
+
+    def check_user(self):
+        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 not self.check_user():
+            raise ControlNotLogin
+        self._user_last_time = time.time()
+
+    def __check_normal_user(self):
+        self.__check_user()
+        if self._user.is_manager():
+            raise UserNotSupportError
+
+    def __check_manager_user(self):
+        self.__check_user()
+        if not self._user.is_manager():
+            raise UserNotSupportError
+
+    def get_user_info(self):
+        self.__check_user()
+        return self._user.get_info()
+
+    def get_uid_no_update(self):
+        if not self.check_user():
+            return ""
+        return self._user.get_uid()
+
+    def get_user_info_no_update(self) -> Dict[str, str]:
+        if not self.check_user():
+            return {}
+        return self._user.get_info()
+
+    def scan(self) -> Tuple[int, any]:
+        """
+        处理扫码事务
+        二维码扫描的任务包括: 登录, 扔垃圾, 标记垃圾
+        :return:
+        """
+        self._cap.get_image()
+        qr_code = self._qr.get_qr_code()
+        if qr_code is None:
+            return GarbageStationStatus.scan_no_to_done, None
+
+        user: Optional[User] = scan_user(qr_code, self._db)
+        if user is not None:
+            return GarbageStationStatus.scan_switch_user, user
+
+        garbage: Optional[GarbageBag] = scan_garbage(qr_code, self._db)
+        if garbage is not None:
+            if self._user is None:
+                raise ControlNotLogin
+            if self._user.is_manager():
+                return GarbageStationStatus.scan_check_garbage, garbage
+            return GarbageStationStatus.scan_throw_garbage, garbage
+
+        return GarbageStationStatus.scan_no_to_done, None
+
+    def get_cap_img(self):
+        return self._cap.get_frame()
+
+    def switch_user(self, user: User) -> bool:
+        """
+        切换用户: 退出/登录
+        :param user: 新用户
+        :return: 登录-True, 退出-False
+        """
+        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 = 0
+            return False
+        self._user = user
+        self._user_last_time = time.time()
+        return True  # 登录
+
+    def __throw_garbage(self, garbage: GarbageBag, garbage_type: enum):
+        self.__check_normal_user()
+        if not self._user.throw_rubbish(garbage, garbage_type, self._loc):
+            raise ThrowGarbageError
+        update_garbage(garbage, self._db)
+        update_user(self._user, self._db)
+
+    def __check_garbage(self, garbage: GarbageBag, check_result: bool):
+        self.__check_manager_user()
+        user = find_user_by_id(garbage.get_user(), self._db)
+        if user is None:
+            raise GarbageBagNotUse
+        if not self._user.check_rubbish(garbage, check_result, user):
+            raise CheckGarbageError
+        update_garbage(garbage, self._db)
+        update_user(self._user, self._db)
+        update_user(user, self._db)
+
+    def creat_garbage(self, path: str, num: int = 1) -> List[tuple[str, Optional[GarbageBag]]]:
+        self.__check_manager_user()
+        if self._user is None:
+            raise ControlNotLogin
+
+        re = []
+        for _ in range(num):
+            gar = creat_new_garbage(self._db)
+            if gar is None:
+                raise CreatGarbageError
+            res = write_gid_qr(gar.get_gid(), path, self._db)
+            re.append(res)
+        return re
+
+    def creat_user(self, name: uname_t, passwd: passwd_t, phone: str, manager: bool) -> Optional[User]:
+        user = creat_new_user(name, passwd, phone, manager, self._db)
+        if user is None:
+            raise CreatUserError
+        return user
+
+    def creat_user_from_list(self, user_list: List[Tuple[uname_t, passwd_t, str]], manager: bool) -> List[User]:
+        re = []
+        for i in user_list:
+            user = creat_new_user(i[0], i[1], i[2], manager, self._db)
+            if user is None:
+                raise CreatUserError
+            re.append(user)
+        return re
+
+    def get_uid_qrcode(self, uid: uid_t, path: str) -> Tuple[str, Optional[User]]:
+        return write_uid_qr(uid, path, self._db)
+
+    def get_uid_qrcode_from_list(self, uid_list: List[uid_t], path: str) -> List[Tuple[str, Optional[User]]]:
+        re = []
+        for uid in uid_list:
+            res = write_uid_qr(uid, path, self._db)
+            re.append(res)
+        return re
+
+    def get_all_uid_qrcode(self, path: str, where: str = "") -> List[str]:
+        return write_all_uid_qr(path, self._db, where=where)
+
+    def ranking(self, limit: int = 0, order_by: str = 'DESC') -> list[Tuple[uid_t, uname_t, score_t, score_t]]:
+        """
+        获取排行榜的功能
+        :return:
+        """
+        if limit > 0:
+            limit = f"LIMIT {int(limit)}"
+        else:
+            limit = ""
+
+        if order_by != 'ASC' and order_by != 'DESC':
+            order_by = 'DESC'
+
+        cur = self._db.search((f"SELECT uid, name, score, reputation "
+                               f"FROM user "
+                               f"WHERE manager = 0 "
+                               f"ORDER BY reputation {order_by}, score {order_by} "
+                               f"{limit}"))
+        if cur is None:
+            raise RankingUserError
+        return list(cur.fetchall())
+
     def to_get_garbage_type(self, garbage: GarbageBag):
         self._flat = GarbageStationStatus.status_get_garbage_type
         self.set_garbage(garbage)
@@ -44,22 +266,10 @@ class GarbageStationStatus:
         self._garbage = garbage
 
     def get_garbage(self) -> Optional[GarbageBag]:
-        if not self._ctrl.check_user():
+        if not self.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):
         self.update_user_time()
         if self._flat != GarbageStationStatus.status_get_garbage_type or self._garbage is None:
@@ -67,7 +277,7 @@ class GarbageStationStatus:
             return
 
         try:
-            self._ctrl.throw_garbage(self._garbage, garbage_type)
+            self.__throw_garbage(self._garbage, garbage_type)
         except (ThrowGarbageError, UserNotSupportError, ControlNotLogin):
             self._win.show_warning("Operation Fail", "The garbage bags have been used.")
             raise
@@ -82,7 +292,7 @@ class GarbageStationStatus:
             return
 
         try:
-            self._ctrl.check_garbage(self._garbage, check)
+            self.__check_garbage(self._garbage, check)
         except (ThrowGarbageError, UserNotSupportError, CheckGarbageError, GarbageBagNotUse):
             self._win.show_warning("Operation Fail", "The garbage bag has been checked")
         finally:
@@ -108,11 +318,11 @@ class GarbageStationStatus:
 
     def show_user_info(self):
         self.update_user_time()
-        if not self._ctrl.check_user():
+        if not self.check_user():
             self._win.show_warning("Operation Fail", "You should login first")
             return
 
-        info = self._ctrl.get_user_info()
+        info = self.get_user_info()
         if info.get('manager', '0') == '1':
             self._win.show_msg("About User", (f"Manager User\n"
                                               f"UserName: {info['name']}\n"
@@ -149,14 +359,11 @@ Run on python {sys.version}
 
     def show_exit(self):
         self.update_user_time()
-        if self._ctrl.is_manager():
+        if self.is_manager():
             self._win.exit_win()
             return
         self._win.show_warning("Exit", f'Permission not permitted'.strip())
 
-    def is_manager(self):
-        return self._ctrl.is_manager()
-
     def easter_eggs(self):
         self.update_user_time()
         if (not self._have_easter_eggs) and random.randint(0, 10) != 1:  # 10% 概率触发
@@ -179,7 +386,7 @@ The function has not yet been implemented.
 
     def get_show_rank(self):
         self.update_user_time()
-        rank_list = self._ctrl.ranking(limit=20)
+        rank_list = self.ranking(limit=20)
         self.rank = [[]]
         for i, r in enumerate(rank_list):
             if len(self.rank[-1]) == 5:
@@ -191,7 +398,7 @@ The function has not yet been implemented.
                 color = "#ffa631"
             elif i == 2:
                 color = "#ff7500"
-            elif r[0] == self._ctrl.get_uid_no_update():
+            elif r[0] == self.get_uid_no_update():
                 color = "#b0a4e3"
             self.rank[-1].append((i + 1, r[1], r[0], r[2], r[3], color))
         if len(self.rank[0]) == 0:
@@ -214,14 +421,16 @@ The function has not yet been implemented.
                             lambda: self.show_rank(+1),
                             self.rank[self.rank_index])
 
-    def update_user_time(self):
-        self._ctrl.update_user_time()
-
 
 class GarbageStation:
-    def __init__(self, ctrl: Control = global_control, refresh_delay: int = conf.tk_refresh_delay):
+    def __init__(self,
+                 db: DB,
+                 cap: HGSCapture,
+                 qr: HGSQRCoder,
+                 loc: location_t = conf.base_location,
+                 refresh_delay: int = conf.tk_refresh_delay):
         self.refresh_delay = refresh_delay
-        self._status = GarbageStationStatus(self, ctrl)
+        self._status = GarbageStationStatus(self, db, cap, qr, loc)
 
         self._window = tk.Tk()
         self._sys_height = self._window.winfo_screenheight()
@@ -781,7 +990,7 @@ class GarbageStation:
             self._garbage_id[2].set(gid)
 
     def update_scan(self):
-        res: Tuple[enum, any] = ControlScanType.no_to_done, None
+        res: Tuple[enum, any] = GarbageStationStatus.scan_no_to_done, None
         try:
             res = self._status.scan()
         except ControlNotLogin:
@@ -793,14 +1002,14 @@ class GarbageStation:
         self._cap_img = ImageTk.PhotoImage(image=_cap_img_info)
         self._cap_label['image'] = self._cap_img
 
-        if res[0] == ControlScanType.switch_user:
+        if res[0] == GarbageStationStatus.scan_switch_user:
             self._status.switch_user(res[1])
             self.update_control()
-        elif res[0] == ControlScanType.throw_garbage:
+        elif res[0] == GarbageStationStatus.scan_throw_garbage:
             self._status.to_get_garbage_type(res[1])
             self.hide_msg_rank()  # 如果有msg也马上隐藏
             self.update_control()
-        elif res[0] == ControlScanType.check_garbage:
+        elif res[0] == GarbageStationStatus.scan_check_garbage:
             self._status.to_get_garbage_check(res[1])
             self._status.show_garbage_info()  # 显示信息
             self.update_control()
@@ -857,5 +1066,8 @@ class GarbageStation:
 
 
 if __name__ == '__main__':
-    station = GarbageStation()
+    mysql_db = DB()
+    capture = HGSCapture()
+    qr_capture = HGSQRCoder(capture)
+    station = GarbageStation(mysql_db, capture, qr_capture)
     station.mainloop()

+ 0 - 1
core/user.py

@@ -3,7 +3,6 @@ import conf
 from tool.type_ import *
 from tool.time_ import HGSTime
 from .garbage import GarbageBag, GarbageType
-from sql.garbage import update_garbage
 
 
 class UserException(Exception):

+ 4 - 3
equipment/scan.py

@@ -6,7 +6,8 @@ from tool.type_ import *
 
 
 class HGSCapture:
-    def __init__(self, capnum: int = 0, *args, **kwargs):
+    def __init__(self, capnum: int = conf.capture_num, *args, **kwargs):
+        args = *args, *conf.capture_arg
         if cv2.CAP_DSHOW not in args:
             args = *args, cv2.CAP_DSHOW
         self._capture = cv2.VideoCapture(capnum, *args, **kwargs)
@@ -93,9 +94,9 @@ class HGSQRCoder:
         return False
 
 
-capture = HGSCapture(capnum=conf.capture_num, *conf.capture_arg)
-qr_capture = HGSQRCoder(capture)
 if __name__ == '__main__':
+    capture = HGSCapture()
+    qr_capture = HGSQRCoder(capture)
     while True:
         capture.get_image()
         qr_data = qr_capture.get_qr_code()

+ 5 - 2
equipment/scan_garbage.py

@@ -1,8 +1,8 @@
 from core.garbage import GarbageBag
-from sql.db import DB, mysql_db
+from sql.db import DB
 from sql.garbage import find_garbage
 from type_ import *
-from scan import QRCode, capture, qr_capture
+from scan import QRCode, HGSCapture, HGSQRCoder
 from tool.pic import write_text
 import re
 import os.path
@@ -74,6 +74,9 @@ def write_all_gid_qr(path: str, db: DB, where: str = "") -> List[Tuple[str,]]:
 
 
 if __name__ == '__main__':
+    mysql_db = DB()
+    capture = HGSCapture()
+    qr_capture = HGSQRCoder(capture)
     write_all_gid_qr("gid", mysql_db)
     while True:
         capture.get_image()

+ 5 - 2
equipment/scan_user.py

@@ -1,9 +1,9 @@
 import conf
 from core.user import User
-from sql.db import DB, mysql_db
+from sql.db import DB
 from sql.user import find_user_by_id
 from type_ import *
-from scan import QRCode, capture, qr_capture
+from scan import QRCode, HGSCapture, HGSQRCoder
 from tool.pic import write_text
 import re
 import os.path
@@ -82,6 +82,9 @@ def write_all_uid_qr(path: str, db: DB, name="nu", where: str = "") -> List[str]
 
 
 if __name__ == '__main__':
+    mysql_db = DB()
+    capture = HGSCapture()
+    qr_capture = HGSQRCoder(capture)
     write_all_uid_qr("uid", mysql_db)
     while True:
         capture.get_image()

+ 0 - 3
sql/db.py

@@ -89,9 +89,6 @@ class DB:
     def done_commit(self):
         self._db.commit()
 
-
-mysql_db = DB()
-
 if __name__ == '__main__':
     # 测试程序
     mysql_db = DB()

+ 2 - 1
sql/garbage.py

@@ -1,6 +1,6 @@
 import time
 from decimal import Decimal
-from db import DB, mysql_db, DBBit, DBDataException, DBDoneException
+from db import DB, DBBit, DBDataException, DBDoneException
 from tool.type_ import *
 from tool.time_ import HGSTime
 from core.garbage import GarbageBag, GarbageType
@@ -145,6 +145,7 @@ def creat_new_garbage(db: DB) -> Optional[GarbageBag]:
 
 
 if __name__ == '__main__':
+    mysql_db = DB()
     bag = creat_new_garbage(mysql_db)
     print(bag)
     bag.config_use(GarbageType.recyclable, HGSTime(), "1e1d30a1f9b78c8fa852d19b4cfaee79", "HuaDu")

+ 2 - 1
sql/user.py

@@ -1,4 +1,4 @@
-from db import DB, mysql_db, DBBit
+from db import DB, DBBit
 from tool.type_ import *
 from tool.login import creat_uid, randomPassword
 from core.user import NormalUser, ManagerUser, User
@@ -84,6 +84,7 @@ def creat_new_user(name: Optional[uname_t], passwd: Optional[passwd_t], phone: p
 
 
 if __name__ == '__main__':
+    mysql_db = DB()
     name_ = 'Huan12'
     usr = find_user_by_name(name_, "123", mysql_db)
     if usr is None: