Explorar el Código

feat: 优化搜素界面和功能

SongZihuan hace 3 años
padre
commit
8295b63ff3
Se han modificado 6 ficheros con 590 adiciones y 67 borrados
  1. 70 19
      control/admin.py
  2. 208 4
      control/admin_event.py
  3. 153 31
      control/admin_program.py
  4. 16 5
      sql/db.py
  5. 106 4
      sql/garbage.py
  6. 37 4
      sql/user.py

+ 70 - 19
control/admin.py

@@ -1,23 +1,29 @@
+import abc
 import tkinter as tk
 import tkinter as tk
-from tkinter import ttk
 from tkinter import messagebox as msg
 from tkinter import messagebox as msg
-import abc
+from tkinter import ttk
 
 
 import conf
 import conf
-from tool.type_ import *
-from tool.tk import make_font
+from core.garbage import GarbageBag
+from core.user import User
+from equipment.scan_garbage import write_gid_qr
+from equipment.scan_user import write_uid_qr, write_all_uid_qr
+from event import TkEventMain
+from sql.db import DB, search_from_garbage_checker_user
+from sql.garbage import (creat_new_garbage, search_from_garbage_view,
+                         del_garbage, del_garbage_not_use, del_garbage_wait_check, del_garbage_has_check,
 
 
-from sql.db import DB
-from sql.user import creat_new_user, del_user, del_user_from_where, del_user_from_where_scan
-from sql.garbage import creat_new_garbage, del_garbage_not_use, del_garbage_not_use_many, find_garbage
+                         del_garbage_where_scan_not_use, del_garbage_where_scan_wait_check,
+                         del_garbage_where_scan_has_check,
 
 
-from equipment.scan_user import write_uid_qr, write_all_uid_qr
-from equipment.scan_garbage import write_gid_qr
+                         del_garbage_where_not_use, del_garbage_where_wait_check, del_garbage_where_has_check,
 
 
-from core.user import User
-from core.garbage import GarbageBag
+                         del_garbage_not_use_many, del_all_garbage, del_all_garbage_scan)
 
 
-from event import TkEventMain
+from sql.user import (creat_new_user, del_user, del_user_from_where, del_user_from_where_scan,
+                      search_user_by_fields, search_from_user_view)
+from tool.tk import make_font
+from tool.type_ import *
 
 
 
 
 class AdminStationException(Exception):
 class AdminStationException(Exception):
@@ -78,9 +84,42 @@ class AdminStationBase(TkEventMain, metaclass=abc.ABCMeta):
     def get_all_uid_qrcode(self, path: str, where: str = "") -> List[str]:
     def get_all_uid_qrcode(self, path: str, where: str = "") -> List[str]:
         return write_all_uid_qr(path, self._db, where=where)
         return write_all_uid_qr(path, self._db, where=where)
 
 
-    def del_garbage(self, gid: gid_t) -> bool:
+    def del_garbage_not_use(self, gid: gid_t) -> bool:
         return del_garbage_not_use(gid, self._db)
         return del_garbage_not_use(gid, self._db)
 
 
+    def del_garbage_wait_check(self, gid: gid_t) -> bool:
+        return del_garbage_wait_check(gid, self._db)
+
+    def del_garbage_has_check(self, gid: gid_t) -> bool:
+        return del_garbage_has_check(gid, self._db)
+
+    def del_garbage(self, gid: gid_t) -> bool:
+        return del_garbage(gid, self._db)
+
+    def del_garbage_where_not_use(self, where) -> int:
+        return del_garbage_where_not_use(where, self._db)
+
+    def del_garbage_where_wait_check(self, where) -> int:
+        return del_garbage_where_wait_check(where, self._db)
+
+    def del_garbage_where_has_check(self, where) -> int:
+        return del_garbage_where_has_check(where, self._db)
+
+    def del_garbage_where_scan_not_use(self, where) -> int:
+        return del_garbage_where_scan_not_use(where, self._db)
+
+    def del_garbage_where_scan_wait_check(self, where) -> int:
+        return del_garbage_where_scan_wait_check(where, self._db)
+
+    def del_garbage_where_scan_has_check(self, where) -> int:
+        return del_garbage_where_scan_has_check(where, self._db)
+
+    def del_all_garbage_scan(self) -> int:
+        return del_all_garbage_scan(self._db)
+
+    def del_all_garbage(self) -> int:
+        return del_all_garbage(self._db)
+
     def del_garbage_many(self, from_: gid_t, to_: gid_t) -> int:
     def del_garbage_many(self, from_: gid_t, to_: gid_t) -> int:
         return del_garbage_not_use_many(from_, to_, self._db)
         return del_garbage_not_use_many(from_, to_, self._db)
 
 
@@ -93,6 +132,18 @@ class AdminStationBase(TkEventMain, metaclass=abc.ABCMeta):
     def del_user_from_where(self, where: str) -> int:
     def del_user_from_where(self, where: str) -> int:
         return del_user_from_where(where, self._db)
         return del_user_from_where(where, self._db)
 
 
+    def search_user(self, columns, uid, name, phone):
+        return search_user_by_fields(columns, uid, name, phone, self._db)
+
+    def search_user_advanced(self, columns, sql):
+        return search_from_user_view(columns, sql, self._db)
+
+    def search_garbage_advanced(self, columns, sql):
+        return search_from_garbage_view(columns, sql, self._db)
+
+    def search_advanced(self, columns, sql):
+        return search_from_garbage_checker_user(columns, sql, self._db)
+
     @abc.abstractmethod
     @abc.abstractmethod
     def login_call(self):
     def login_call(self):
         ...
         ...
@@ -174,9 +225,9 @@ class AdminStation(AdminStationBase):
         self._program_now: Optional[Tuple[str, tk.Frame, tk_program.AdminProgram]] = None
         self._program_now: Optional[Tuple[str, tk.Frame, tk_program.AdminProgram]] = None
 
 
         self.__conf_font_size()
         self.__conf_font_size()
-        self.__conf_creak_tk()
-        self.__conf_creak_menu()
-        self.__conf_creak_program()
+        self.__conf_create_tk()
+        self.__conf_create_menu()
+        self.__conf_create_program()
         self.__conf_tk()
         self.__conf_tk()
         # self.__show_login_window()
         # self.__show_login_window()
 
 
@@ -189,7 +240,7 @@ class AdminStation(AdminStationBase):
         self._window.resizable(False, False)
         self._window.resizable(False, False)
         self._window.protocol("WM_DELETE_WINDOW", lambda: self.main_exit())
         self._window.protocol("WM_DELETE_WINDOW", lambda: self.main_exit())
 
 
-    def __conf_creak_tk(self):
+    def __conf_create_tk(self):
         self._menu_back = tk.Frame(self._window)
         self._menu_back = tk.Frame(self._window)
         self._menu_line = tk.Label(self._menu_back)  # 下划线
         self._menu_line = tk.Label(self._menu_back)  # 下划线
         self._menu_title: Tuple[tk.Label, tk.Variable] = tk.Label(self._menu_back), tk.StringVar()
         self._menu_title: Tuple[tk.Label, tk.Variable] = tk.Label(self._menu_back), tk.StringVar()
@@ -283,7 +334,7 @@ class AdminStation(AdminStationBase):
         self._menu_list.pop()  # 弹出最后一个元素
         self._menu_list.pop()  # 弹出最后一个元素
         self.to_menu(self._menu_list.pop())  # 再弹出一个元素
         self.to_menu(self._menu_list.pop())  # 再弹出一个元素
 
 
-    def __conf_creak_menu(self):
+    def __conf_create_menu(self):
         frame_list = []
         frame_list = []
 
 
         for i in tk_menu.all_menu:
         for i in tk_menu.all_menu:
@@ -345,7 +396,7 @@ class AdminStation(AdminStationBase):
         self._program_title[0]['textvariable'] = self._program_title[1]
         self._program_title[0]['textvariable'] = self._program_title[1]
         # 不立即显示
         # 不立即显示
 
 
-    def __conf_creak_program(self):
+    def __conf_create_program(self):
         program_list = []
         program_list = []
         for i in tk_program.all_program:
         for i in tk_program.all_program:
             program_list.append(i(self, self._program_back, conf.tk_win_bg))
             program_list.append(i(self, self._program_back, conf.tk_win_bg))

+ 208 - 4
control/admin_event.py

@@ -2,15 +2,14 @@ import time
 
 
 from tool.type_ import *
 from tool.type_ import *
 from sql.db import DB
 from sql.db import DB
-from sql.user import find_user_by_name, creat_new_user
-from sql.garbage import creat_new_garbage
+from sql.user import find_user_by_name
 
 
 from core.user import User
 from core.user import User
 from core.garbage import GarbageBag
 from core.garbage import GarbageBag
 
 
-from event import TkEventBase, TkThreading, TkEventException
+from event import TkEventBase, TkThreading
 import admin
 import admin
-
+import admin_program
 
 
 class AdminEventBase(TkEventBase):
 class AdminEventBase(TkEventBase):
     def __init__(self, station):
     def __init__(self, station):
@@ -146,3 +145,208 @@ class DelUserFromWhereEvent(AdminEventBase):
             self.station.show_msg("DeleteUser", f"Delete {res} user success")
             self.station.show_msg("DeleteUser", f"Delete {res} user success")
         else:
         else:
             self.station.show_msg("DeleteUserError", f"`Where` must be SQL")
             self.station.show_msg("DeleteUserError", f"`Where` must be SQL")
+
+
+class DelGarbageEvent(AdminEventBase):
+    def func(self, gid, where):
+        if where == 0:
+            return 1 if self.station.del_garbage(gid) else -1
+        elif where == 1:
+            return 1 if self.station.del_garbage_not_use(gid) else -1
+        elif where == 2:
+            return 1 if self.station.del_garbage_wait_check(gid) else -1
+        elif where == 3:
+            return 1 if self.station.del_garbage_has_check(gid) else -1
+        return -1
+
+    def __init__(self, station):
+        super(DelGarbageEvent, self).__init__(station)
+
+    def start(self, gid, where):
+        self.thread = TkThreading(self.func, gid, where)
+        return self
+
+    def done_after_event(self):
+        res: int = self.thread.wait_event()
+        if res != -1:
+            self.station.show_msg("DeleteGarbage", f"Delete {res} garbage success")
+        else:
+            self.station.show_msg("DeleteGarbageError", f"Delete error")
+
+
+class DelGarbageWhereEvent(AdminEventBase):
+    def func(self, where, where_sql):
+        if where == 1:
+            return self.station.del_garbage_where_not_use(where_sql)
+        elif where == 2:
+            return self.station.del_garbage_where_wait_check(where_sql)
+        elif where == 3:
+            return self.station.del_garbage_where_has_check(where_sql)
+        return -1
+
+    def __init__(self, station):
+        super(DelGarbageWhereEvent, self).__init__(station)
+
+    def start(self, where, where_sql):
+        self.thread = TkThreading(self.func, where, where_sql)
+        return self
+
+    def done_after_event(self):
+        res: int = self.thread.wait_event()
+        if res != -1:
+            self.station.show_msg("DeleteGarbage", f"Delete {res} garbage success")
+        else:
+            self.station.show_msg("DeleteGarbageError", f"Delete error")
+
+
+class DelGarbageWhereScanEvent(AdminEventBase):
+    def func(self, where, where_sql):
+        if where == 1:
+            return self.station.del_garbage_where_scan_not_use(where_sql)
+        elif where == 2:
+            return self.station.del_garbage_where_scan_wait_check(where_sql)
+        elif where == 3:
+            return self.station.del_garbage_where_scan_has_check(where_sql)
+        return -1
+
+    def __init__(self, station):
+        super(DelGarbageWhereScanEvent, self).__init__(station)
+
+    def start(self, where, where_sql):
+        self.thread = TkThreading(self.func, where, where_sql)
+        return self
+
+    def done_after_event(self):
+        res: int = self.thread.wait_event()
+        if res != -1:
+            self.station.show_msg("DeleteGarbageScan", f"Delete count: {res}")
+        else:
+            self.station.show_msg("DeleteGarbageScanError", f"Delete scan error")
+
+
+class DelAllGarbageScanEvent(AdminEventBase):
+    def func(self):
+        return self.station.del_all_garbage_scan()
+
+    def __init__(self, station):
+        super(DelAllGarbageScanEvent, self).__init__(station)
+        self.thread = TkThreading(self.func)
+
+    def done_after_event(self):
+        res: int = self.thread.wait_event()
+        if res != -1:
+            self.station.show_msg("DeleteAllGarbageScan", f"Delete count: {res}")
+        else:
+            self.station.show_msg("DeleteAllGarbageError", f"Delete scan error")
+
+
+class DelAllGarbageEvent(AdminEventBase):
+    def func(self):
+        return self.station.del_all_garbage()
+
+    def __init__(self, station):
+        super(DelAllGarbageEvent, self).__init__(station)
+        self.thread = TkThreading(self.func)
+
+    def done_after_event(self):
+        res: int = self.thread.wait_event()
+        if res != -1:
+            self.station.show_msg("DeleteAllGarbage", f"Delete all[{res}] garbage success")
+        else:
+            self.station.show_msg("DeleteAllGarbageError", f"Delete error")
+
+
+class SearchUserEvent(AdminEventBase):
+    def func(self, columns, uid, name, phone):
+        return self.station.search_user(columns, uid, name, phone)
+
+    def __init__(self, station):
+        super(SearchUserEvent, self).__init__(station)
+        self.program: Optional[admin_program.SearchUserProgram] = None
+
+    def start(self, columns, uid, name, phone, program):
+        self.thread = TkThreading(self.func, columns, uid, name, phone)
+        self.program = program
+        return self
+
+    def done_after_event(self):
+        res: list[list] = self.thread.wait_event()
+        if res is None or self.program is None:
+            self.station.show_msg("Search User Error", f"Search error")
+            return
+        for i in self.program.view.get_children():
+            self.program.view.delete(i)
+        for i in res:
+            self.program.view.insert('', 'end', values=i)
+
+
+class SearchUserAdvancedEvent(AdminEventBase):
+    def func(self, columns, sql):
+        return self.station.search_user_advanced(columns, sql)
+
+    def __init__(self, station):
+        super(SearchUserAdvancedEvent, self).__init__(station)
+        self.program: Optional[admin_program.SearchUserAdvancedProgram] = None
+
+    def start(self, columns, sql, program):
+        self.thread = TkThreading(self.func, columns, sql)
+        self.program = program
+        return self
+
+    def done_after_event(self):
+        res: list[list] = self.thread.wait_event()
+        if res is None or self.program is None:
+            self.station.show_msg("Search User Advanced Error", f"Search error")
+            return
+        for i in self.program.view.get_children():
+            self.program.view.delete(i)
+        for i in res:
+            self.program.view.insert('', 'end', values=i)
+
+
+class SearchGarbageAdvancedEvent(AdminEventBase):
+    def func(self, columns, sql):
+        return self.station.search_garbage_advanced(columns, sql)
+
+    def __init__(self, station):
+        super(SearchGarbageAdvancedEvent, self).__init__(station)
+        self.program: Optional[admin_program.SearchGarbageAdvancedProgram] = None
+
+    def start(self, columns, sql, program):
+        self.thread = TkThreading(self.func, columns, sql)
+        self.program = program
+        return self
+
+    def done_after_event(self):
+        res: list[list] = self.thread.wait_event()
+        if res is None or self.program is None:
+            self.station.show_msg("Search Garbage Advanced Error", f"Search error")
+            return
+        for i in self.program.view.get_children():
+            self.program.view.delete(i)
+        for i in res:
+            self.program.view.insert('', 'end', values=i)
+
+
+class SearchAdvancedEvent(AdminEventBase):
+    def func(self, columns, sql):
+        return self.station.search_advanced(columns, sql)
+
+    def __init__(self, station):
+        super(SearchAdvancedEvent, self).__init__(station)
+        self.program: Optional[admin_program.SearchAdvancedProgram] = None
+
+    def start(self, columns, sql, program):
+        self.thread = TkThreading(self.func, columns, sql)
+        self.program = program
+        return self
+
+    def done_after_event(self):
+        res: list[list] = self.thread.wait_event()
+        if res is None or self.program is None:
+            self.station.show_msg("Search Advanced Error", f"Search error")
+            return
+        for i in self.program.view.get_children():
+            self.program.view.delete(i)
+        for i in res:
+            self.program.view.insert('', 'end', values=i)

+ 153 - 31
control/admin_program.py

@@ -11,6 +11,7 @@ import conf
 import admin
 import admin
 import admin_event as tk_event
 import admin_event as tk_event
 
 
+from sql.user import find_user_by_name
 from core.garbage import GarbageType
 from core.garbage import GarbageType
 
 
 
 
@@ -520,15 +521,16 @@ class DeleteGarbageProgramBase(AdminProgram):
 
 
         self.int_var: tk.Variable = tk.IntVar()
         self.int_var: tk.Variable = tk.IntVar()
         self.int_var.set(0)
         self.int_var.set(0)
-        self.radio: List[tk.Radiobutton] = [tk.Radiobutton(self.frame) for _ in range(4)]  # del, scan
-        self.btn: List[tk.Button] = [tk.Button(self.frame) for _ in range(2)]  # del, scan
+        self.radio: List[tk.Radiobutton] = [tk.Radiobutton(self.frame) for _ in range(4)]
+        self.btn: tk.Button = tk.Button(self.frame)
 
 
         self.__conf_font()
         self.__conf_font()
         self._conf()
         self._conf()
 
 
-    def _conf(self, title: str = "GarbageID:", color: str = "#b69968"):
+    def _conf(self, title: str = "GarbageID:", color: str = "#b69968", support_del_all: bool = True):
         self.frame_title = title
         self.frame_title = title
         self.frame_color = color
         self.frame_color = color
+        self.support_del_all = support_del_all
 
 
     def __conf_font(self, n: int = 1):
     def __conf_font(self, n: int = 1):
         self.title_font_size = int(16 * n)
         self.title_font_size = int(16 * n)
@@ -565,24 +567,89 @@ class DeleteGarbageProgramBase(AdminProgram):
             radio['variable'] = self.int_var
             radio['variable'] = self.int_var
             radio['anchor'] = 'w'
             radio['anchor'] = 'w'
 
 
+        if not self.support_del_all:
+            self.int_var.set(1)
+            self.radio[0]['state'] = 'disable'
+
         self.radio[0].place(relx=0.20, rely=0.43, relwidth=0.20, relheight=0.1)
         self.radio[0].place(relx=0.20, rely=0.43, relwidth=0.20, relheight=0.1)
         self.radio[1].place(relx=0.60, rely=0.43, relwidth=0.20, relheight=0.1)
         self.radio[1].place(relx=0.60, rely=0.43, relwidth=0.20, relheight=0.1)
         self.radio[2].place(relx=0.20, rely=0.55, relwidth=0.20, relheight=0.1)
         self.radio[2].place(relx=0.20, rely=0.55, relwidth=0.20, relheight=0.1)
         self.radio[3].place(relx=0.60, rely=0.55, relwidth=0.20, relheight=0.1)
         self.radio[3].place(relx=0.60, rely=0.55, relwidth=0.20, relheight=0.1)
 
 
-        for btn, text, x in zip(self.btn, ["Delete", "Scan"], [0.2, 0.6]):
-            btn['font'] = btn_font
-            btn['text'] = text
-            btn['bg'] = conf.tk_btn_bg
-            btn.place(relx=x, rely=0.68, relwidth=0.2, relheight=0.08)
+        self.btn['font'] = btn_font
+        self.btn['text'] = 'Delete'
+        self.btn['bg'] = conf.tk_btn_bg
+        self.btn['command'] = lambda: self.delete_garbage()
+        self.btn.place(relx=0.4, rely=0.68, relwidth=0.2, relheight=0.08)
+
+    def delete_garbage(self):
+        ...
 
 
     def set_disable(self):
     def set_disable(self):
-        set_tk_disable_from_list(self.btn)
         self.enter['state'] = 'disable'
         self.enter['state'] = 'disable'
+        self.btn['state'] = 'disable'
 
 
     def reset_disable(self):
     def reset_disable(self):
-        set_tk_disable_from_list(self.btn, flat='normal')
         self.enter['state'] = 'normal'
         self.enter['state'] = 'normal'
+        self.btn['state'] = 'normal'
+
+
+class DeleteGarbageProgram(DeleteGarbageProgramBase):
+    def __init__(self, station, win, color):
+        super(DeleteGarbageProgram, self).__init__(station, win, color, "DeleteGarbage")
+
+    def delete_garbage(self):
+        where = self.int_var.get()
+        assert where in [0, 1, 2, 3]
+
+        gid = self.var.get()
+        if len(gid) == 0:
+            self.station.show_msg("GarbageID Error", "You should enter the garbage id", "Warning")
+            return
+
+        event = tk_event.DelGarbageEvent(self.station).start(gid, where)
+        self.station.push_event(event)
+
+
+class DeleteGarbageMoreProgram(DeleteGarbageProgramBase):
+    def __init__(self, station, win, color):
+        super(DeleteGarbageMoreProgram, self).__init__(station, win, color, "DeleteGarbageMore")
+        self.scan_btn = tk.Button(self.frame)
+        self._conf("Where:", "#f58f98", False)
+
+    def conf_gui(self, n: int = 1):
+        super(DeleteGarbageMoreProgram, self).conf_gui(n)
+        self.btn.place_forget()
+        self.btn.place(relx=0.2, rely=0.68, relwidth=0.2, relheight=0.08)
+
+        self.scan_btn['font'] = make_font(size=self.btn_font_size)
+        self.scan_btn['text'] = 'Scan'
+        self.scan_btn['bg'] = conf.tk_btn_bg
+        self.scan_btn['command'] = lambda: self.delete_garbage(True)
+        self.scan_btn.place(relx=0.6, rely=0.68, relwidth=0.2, relheight=0.08)
+
+    def set_disable(self):
+        super(DeleteGarbageMoreProgram, self).set_disable()
+        self.scan_btn['state'] = 'disable'
+
+    def reset_disable(self):
+        super(DeleteGarbageMoreProgram, self).reset_disable()
+        self.scan_btn['state'] = 'normal'
+
+    def delete_garbage(self, is_scan: bool = False):
+        where = self.int_var.get()
+        assert where in [1, 2, 3]
+
+        where_sql = self.var.get()
+        if len(where_sql) == 0:
+            self.station.show_msg("`Where`Error", "`Where` must be SQL", "Warning")
+            return
+
+        if is_scan:
+            event = tk_event.DelGarbageWhereScanEvent(self.station).start(where, where_sql)
+        else:
+            event = tk_event.DelGarbageWhereEvent(self.station).start(where, where_sql)
+        self.station.push_event(event)
 
 
 
 
 class DeleteAllGarbageProgram(AdminProgram):
 class DeleteAllGarbageProgram(AdminProgram):
@@ -647,8 +714,28 @@ class DeleteAllGarbageProgram(AdminProgram):
 
 
         self.btn[0]['font'] = danger_btn_font
         self.btn[0]['font'] = danger_btn_font
         self.btn[0]['bg'] = "#f20c00"
         self.btn[0]['bg'] = "#f20c00"
+        self.btn[0]['command'] = lambda: self.delete_garbage()
+
         self.btn[1]['font'] = btn_font
         self.btn[1]['font'] = btn_font
         self.btn[1]['bg'] = conf.tk_btn_bg
         self.btn[1]['bg'] = conf.tk_btn_bg
+        self.btn[1]['command'] = lambda: self.scan_garbage()
+
+    def scan_garbage(self):
+        event = tk_event.DelAllGarbageScanEvent(self.station)  # 不需要start
+        self.station.push_event(event)
+
+    def delete_garbage(self):
+        passwd = self.var.get()
+        if len(passwd) == 0:
+            self.station.show_msg("PassWordError", "Password error", "Warning")
+
+        user = find_user_by_name('admin', passwd, self.station.get_db())
+        if user is None or not user.is_manager():
+            self.station.show_msg("PassWordError", "Password error", "Warning")
+            return
+
+        event = tk_event.DelAllGarbageEvent(self.station)  # 不需要start
+        self.station.push_event(event)
 
 
     def set_disable(self):
     def set_disable(self):
         set_tk_disable_from_list(self.btn)
         set_tk_disable_from_list(self.btn)
@@ -659,17 +746,6 @@ class DeleteAllGarbageProgram(AdminProgram):
         self.enter['state'] = 'normal'
         self.enter['state'] = 'normal'
 
 
 
 
-class DeleteGarbageProgram(DeleteGarbageProgramBase):
-    def __init__(self, station, win, color):
-        super(DeleteGarbageProgram, self).__init__(station, win, color, "DeleteGarbage")
-
-
-class DeleteGarbageMoreProgram(DeleteGarbageProgramBase):
-    def __init__(self, station, win, color):
-        super(DeleteGarbageMoreProgram, self).__init__(station, win, color, "DeleteGarbageMore")
-        self._conf("Where:", "#f58f98")
-
-
 class SearchBaseProgram(AdminProgram, metaclass=abc.ABCMeta):
 class SearchBaseProgram(AdminProgram, metaclass=abc.ABCMeta):
     def __init__(self, station, win, color, title: str):
     def __init__(self, station, win, color, title: str):
         super().__init__(station, win, color, title)
         super().__init__(station, win, color, title)
@@ -717,6 +793,7 @@ class SearchUserProgram(SearchBaseProgram):
         self.check: List[Tuple[tk.Checkbutton, tk.Variable]] = [(tk.Checkbutton(self.enter_frame), tk.IntVar())
         self.check: List[Tuple[tk.Checkbutton, tk.Variable]] = [(tk.Checkbutton(self.enter_frame), tk.IntVar())
                                                                 for _ in range(3)]
                                                                 for _ in range(3)]
         self.btn: tk.Button = tk.Button(self.frame)
         self.btn: tk.Button = tk.Button(self.frame)
+        self._columns = ["UserID", "Name", "Phone", "Score", "Reputation", "IsManager"]
         self.__conf_font()
         self.__conf_font()
 
 
     def __conf_font(self, n: int = 1):
     def __conf_font(self, n: int = 1):
@@ -760,10 +837,35 @@ class SearchUserProgram(SearchBaseProgram):
         self.btn['font'] = btn_font
         self.btn['font'] = btn_font
         self.btn['text'] = "Search"
         self.btn['text'] = "Search"
         self.btn['bg'] = conf.tk_btn_bg
         self.btn['bg'] = conf.tk_btn_bg
+        self.btn['command'] = self.search_user
         self.btn.place(relx=0.4, rely=0.9, relwidth=0.2, relheight=0.08)
         self.btn.place(relx=0.4, rely=0.9, relwidth=0.2, relheight=0.08)
 
 
-        columns = ["UserID", "UserName", "Phone", "Score", "Reputation", "Rubbish"]
-        self.conf_view_gui(columns, relx=0.05, rely=0.32, relwidth=0.9, relheight=0.55)
+        self.conf_view_gui(self._columns, relx=0.05, rely=0.32, relwidth=0.9, relheight=0.55)
+
+    def search_user(self):
+        use_uid = self.check[0][1].get()
+        use_name = self.check[1][1].get()
+        use_phone = self.check[2][1].get()
+        uid = None
+        name = None
+        phone = None
+        if use_uid:
+            uid = self.var[0].get()
+            if len(uid) == 0:
+                uid = None
+
+        if use_name:
+            name = self.var[1].get()
+            if len(name) == 0:
+                name = None
+
+        if use_phone:
+            phone = self.var[2].get()
+            if len(phone) == 0:
+                phone = None
+
+        event = tk_event.SearchUserEvent(self.station).start(self._columns, uid, name, phone, self)
+        self.station.push_event(event)
 
 
     def set_disable(self):
     def set_disable(self):
         self.btn['state'] = 'disable'
         self.btn['state'] = 'disable'
@@ -774,7 +876,7 @@ class SearchUserProgram(SearchBaseProgram):
         set_tk_disable_from_list(self.enter, flat='normal')
         set_tk_disable_from_list(self.enter, flat='normal')
 
 
 
 
-class SearchUserAdvancedProgramBase(SearchBaseProgram, metaclass=abc.ABCMeta):
+class SearchAdvancedProgramBase(SearchBaseProgram, metaclass=abc.ABCMeta):
     def __init__(self, station, win, color, title: str):
     def __init__(self, station, win, color, title: str):
         super().__init__(station, win, color, title)
         super().__init__(station, win, color, title)
 
 
@@ -821,10 +923,14 @@ class SearchUserAdvancedProgramBase(SearchBaseProgram, metaclass=abc.ABCMeta):
         self.btn['text'] = "Search"
         self.btn['text'] = "Search"
         self.btn['font'] = btn_font
         self.btn['font'] = btn_font
         self.btn['bg'] = conf.tk_btn_bg
         self.btn['bg'] = conf.tk_btn_bg
+        self.btn['command'] = self.search
         self.btn.place(relx=0.4, rely=0.9, relwidth=0.2, relheight=0.08)
         self.btn.place(relx=0.4, rely=0.9, relwidth=0.2, relheight=0.08)
 
 
         self.conf_view_gui(self._columns, relx=0.05, rely=0.12, relwidth=0.9, relheight=0.76)
         self.conf_view_gui(self._columns, relx=0.05, rely=0.12, relwidth=0.9, relheight=0.76)
 
 
+    def search(self):
+        ...
+
     def set_disable(self):
     def set_disable(self):
         self.btn['state'] = 'disable'
         self.btn['state'] = 'disable'
         self.enter['state'] = 'disable'
         self.enter['state'] = 'disable'
@@ -834,12 +940,17 @@ class SearchUserAdvancedProgramBase(SearchBaseProgram, metaclass=abc.ABCMeta):
         self.enter['state'] = 'normal'
         self.enter['state'] = 'normal'
 
 
 
 
-class SearchUserAdvancedProgram(SearchUserAdvancedProgramBase):
+class SearchUserAdvancedProgram(SearchAdvancedProgramBase):
     def __init__(self, station, win, color):
     def __init__(self, station, win, color):
         super(SearchUserAdvancedProgram, self).__init__(station, win, color, "SearchUserAdvanced")
         super(SearchUserAdvancedProgram, self).__init__(station, win, color, "SearchUserAdvanced")
-        columns = ["UserID", "UserName", "Phone", "Score", "Reputation", "Rubbish"]
+        columns = ["UserID", "Name", "Phone", "Score", "Reputation", "IsManager"]
         self._conf(columns, '#48c0a3')
         self._conf(columns, '#48c0a3')
 
 
+    def search(self):
+        where = self.var.get()
+        event = tk_event.SearchUserAdvancedEvent(self.station).start(self._columns, where, self)
+        self.station.push_event(event)
+
 
 
 class SearchGarbageProgram(SearchBaseProgram):
 class SearchGarbageProgram(SearchBaseProgram):
     def __init__(self, station, win, color):
     def __init__(self, station, win, color):
@@ -910,20 +1021,31 @@ class SearchGarbageProgram(SearchBaseProgram):
         set_tk_disable_from_list(self.enter, flat='normal')
         set_tk_disable_from_list(self.enter, flat='normal')
 
 
 
 
-class SearchGarbageAdvancedProgram(SearchUserAdvancedProgramBase):
+class SearchGarbageAdvancedProgram(SearchAdvancedProgramBase):
     def __init__(self, station, win, color):
     def __init__(self, station, win, color):
         super(SearchGarbageAdvancedProgram, self).__init__(station, win, color, "SearchGarbageAdvanced")
         super(SearchGarbageAdvancedProgram, self).__init__(station, win, color, "SearchGarbageAdvanced")
-        columns = ["GarbageID", "UserID", "CheckerID", "UseTime", "Location", "GarbageType", "CheckResult"]
+        columns = ["GarbageID", "UserID", "CheckerID", "CreatTime", "UseTime", "Location", "GarbageType", "CheckResult"]
         self._conf(columns, '#d1923f')
         self._conf(columns, '#d1923f')
 
 
+    def search(self):
+        where = self.var.get()
+        event = tk_event.SearchGarbageAdvancedEvent(self.station).start(self._columns, where, self)
+        self.station.push_event(event)
 
 
-class SearchAdvancedProgram(SearchUserAdvancedProgramBase):
+
+class SearchAdvancedProgram(SearchAdvancedProgramBase):
     def __init__(self, station, win, color):
     def __init__(self, station, win, color):
         super(SearchAdvancedProgram, self).__init__(station, win, color, "SearchAdvanced")
         super(SearchAdvancedProgram, self).__init__(station, win, color, "SearchAdvanced")
-        columns = ["GarbageID", "UserID", "UserName", "Phone", "Score", "Reputation", "Rubbish",
-                   "CheckerID", "CheckerName", "CheckerPhone", "UseTime", "Location", "GarbageType", "CheckResult"]
+        columns = ["GarbageID", "UserID", "UserName", "UserPhone", "UserScore",
+                   "UserReputation", "CheckerID", "CheckerName", "CheckerPhone",
+                   "CreateTime", "UseTime", "Location", "GarbageType", "CheckResult"]
         self._conf(columns, '#426ab3')
         self._conf(columns, '#426ab3')
 
 
+    def search(self):
+        where = self.var.get()
+        event = tk_event.SearchAdvancedEvent(self.station).start(self._columns, where, self)
+        self.station.push_event(event)
+
 
 
 class UpdateUserProgramBase(AdminProgram):
 class UpdateUserProgramBase(AdminProgram):
     def __init__(self, station, win, color, title: str):
     def __init__(self, station, win, color, title: str):

+ 16 - 5
sql/db.py

@@ -92,7 +92,6 @@ class DB:
             self._cursor.execute(sql)
             self._cursor.execute(sql)
         except pymysql.MySQLError:
         except pymysql.MySQLError:
             self._db.rollback()
             self._db.rollback()
-            raise
         finally:
         finally:
             self._lock.release()
             self._lock.release()
         return self._cursor
         return self._cursor
@@ -105,14 +104,26 @@ class DB:
             self._lock.release()
             self._lock.release()
 
 
 
 
+def search_from_garbage_checker_user(columns, where, db: DB):
+    if len(where) > 0:
+        where = f"WHERE {where} "
+
+    column = ", ".join(columns)
+    cur = db.search(f"SELECT {column} FROM garbage_checker_user {where};")
+    if cur is None:
+        return None
+    res = cur.fetchall()
+    return res
+
+
 if __name__ == '__main__':
 if __name__ == '__main__':
     # 测试程序
     # 测试程序
     mysql_db = DB()
     mysql_db = DB()
     mysql_db.search("SELECT * FROM user;")
     mysql_db.search("SELECT * FROM user;")
-    res = mysql_db.get_cursor().fetchall()
-    print(res)
+    res_ = mysql_db.get_cursor().fetchall()
+    print(res_)
 
 
     mysql_db.search("SELECT * FROM user WHERE uid = 0;")
     mysql_db.search("SELECT * FROM user WHERE uid = 0;")
-    res = mysql_db.get_cursor().fetchall()
-    print(res)
+    res_ = mysql_db.get_cursor().fetchall()
+    print(res_)
     mysql_db.close()
     mysql_db.close()

+ 106 - 4
sql/garbage.py

@@ -10,7 +10,20 @@ class GarbageDBException(DBDataException):
     ...
     ...
 
 
 
 
-def countGarbageByTime(uid: uid_t, db: DB):
+def search_from_garbage_view(columns, where: str, db: DB):
+    if len(where) > 0:
+        where = f"WHERE {where} "
+
+    column = ", ".join(columns)
+    print(f"SELECT {column} FROM garbage_view {where};")
+    cur = db.search(f"SELECT {column} FROM garbage_view {where};")
+    if cur is None:
+        return None
+    res = cur.fetchall()
+    return res
+
+
+def count_garbage_by_time(uid: uid_t, db: DB):
     ti: time_t = time.time()
     ti: time_t = time.time()
     start = ti - 3.5 * 24 * 60 * 60  # 前后3.5天
     start = ti - 3.5 * 24 * 60 * 60  # 前后3.5天
     end = ti + 3.5 * 24 * 60 * 60
     end = ti + 3.5 * 24 * 60 * 60
@@ -144,8 +157,8 @@ def creat_new_garbage(db: DB) -> Optional[GarbageBag]:
     return GarbageBag(str(gid))
     return GarbageBag(str(gid))
 
 
 
 
-def del_garbage_not_use(gid: gid_t, db: DB) -> bool:
-    cur = db.done(f"DELETE FROM garbage_n WHERE gid = {gid};")
+def del_garbage_core(gid: gid_t, db: DB, from_: str) -> bool:
+    cur = db.done(f"DELETE FROM {from_} WHERE gid = {gid};")
     if cur is None or cur.rowcount == 0:
     if cur is None or cur.rowcount == 0:
         return False
         return False
     assert cur.rowcount == 1
     assert cur.rowcount == 1
@@ -156,6 +169,95 @@ def del_garbage_not_use(gid: gid_t, db: DB) -> bool:
     return True
     return True
 
 
 
 
+def del_garbage_not_use(gid: gid_t, db: DB) -> bool:
+    return del_garbage_core(gid, db, "garbage_n")
+
+
+def del_garbage_wait_check(gid: gid_t, db: DB) -> bool:
+    return del_garbage_core(gid, db, "garbage_c")
+
+
+def del_garbage_has_check(gid: gid_t, db: DB) -> bool:
+    return del_garbage_core(gid, db, "garbage_u")
+
+
+def del_garbage(gid, db: DB):
+    res = del_garbage_not_use(gid, db)
+    if res:
+        return True
+    res = del_garbage_wait_check(gid, db)
+    if res:
+        return True
+    return del_garbage_has_check(gid, db)
+
+
+def del_garbage_where_core(where, db: DB, from_: str, from_int: int) -> int:
+    cur = db.done_(f"DELETE FROM {from_} WHERE {where};")
+    if cur is None:
+        return -1
+    elif cur.rowcount == 0:
+        return 0
+
+    cur = db.done(f"DELETE FROM garbage WHERE flat={from_int} AND gid NOT IN (SELECT gid FROM {from_});")
+    if cur is None:
+        return -1
+    return cur.rowcount
+
+
+def del_garbage_where_not_use(where, db: DB) -> int:
+    return del_garbage_where_core(where, db, "garbage_n", 0)
+
+
+def del_garbage_where_wait_check(where, db: DB) -> int:
+    return del_garbage_where_core(where, db, "garbage_c", 1)
+
+
+def del_garbage_where_has_check(where, db: DB) -> int:
+    return del_garbage_where_core(where, db, "garbage_u", 2)
+
+
+def del_garbage_where_scan_core(where, db: DB, from_: str) -> int:
+    cur = db.done(f"SELECT gid FROM {from_} WHERE {where};")
+    if cur is None:
+        return -1
+    return cur.rowcount
+
+
+def del_garbage_where_scan_not_use(where, db: DB) -> int:
+    return del_garbage_where_scan_core(where, db, "garbage_n")
+
+
+def del_garbage_where_scan_wait_check(where, db: DB) -> int:
+    return del_garbage_where_scan_core(where, db, "garbage_c")
+
+
+def del_garbage_where_scan_has_check(where, db: DB) -> int:
+    return del_garbage_where_scan_core(where, db, "garbage_u")
+
+
+def del_all_garbage(db: DB) -> int:
+    cur = db.done(f"DELETE FROM garbage_u WHERE 1;")
+    if cur is None:
+        return -1
+    cur = db.done(f"DELETE FROM garbage_c WHERE 1;")
+    if cur is None:
+        return -1
+    cur = db.done(f"DELETE FROM garbage_n WHERE 1;")
+    if cur is None:
+        return -1
+    cur = db.done(f"DELETE FROM garbage WHERE 1;")
+    if cur is None:
+        return -1
+    return cur.rowcount
+
+
+def del_all_garbage_scan(db: DB) -> int:
+    cur = db.done(f"SELECT gid FROM garbage WHERE 1;")
+    if cur is None:
+        return -1
+    return cur.rowcount
+
+
 def del_garbage_not_use_many(gid_from: gid_t, gid_to: gid_t, db: DB) -> int:
 def del_garbage_not_use_many(gid_from: gid_t, gid_to: gid_t, db: DB) -> int:
     cur = db.done(f"DELETE FROM garbage "
     cur = db.done(f"DELETE FROM garbage "
                   f"WHERE gid IN (SELECT gid FROM garbage_n WHERE gid BETWEEN {gid_from} and {gid_to});")
                   f"WHERE gid IN (SELECT gid FROM garbage_n WHERE gid BETWEEN {gid_from} and {gid_to});")
@@ -185,4 +287,4 @@ if __name__ == '__main__':
     bag = find_garbage(bag.get_gid(), mysql_db)
     bag = find_garbage(bag.get_gid(), mysql_db)
     print(bag)
     print(bag)
 
 
-    print(countGarbageByTime("1e1d30a1f9b78c8fa852d19b4cfaee79", mysql_db))
+    print(count_garbage_by_time("1e1d30a1f9b78c8fa852d19b4cfaee79", mysql_db))

+ 37 - 4
sql/user.py

@@ -3,7 +3,39 @@ from tool.type_ import *
 from tool.login import creat_uid, randomPassword
 from tool.login import creat_uid, randomPassword
 from core.user import NormalUser, ManagerUser, User
 from core.user import NormalUser, ManagerUser, User
 import conf
 import conf
-from garbage import countGarbageByTime
+from garbage import count_garbage_by_time
+
+
+def search_user_by_fields(columns, uid: uid_t, name: uname_t, phone: phone_t, db: DB):
+    where = ""
+    if uid is not None:
+        where += f"UserID=‘{uid}’ AND "
+    if name is not None:
+        where += f"Name='{name}' AND "
+    if phone is not None:
+        where += f"Phone='{phone}' AND "
+
+    if len(where) != 0:
+        where = where[0:-4]  # 去除末尾的AND
+
+    return search_from_user_view(columns, where, db)
+
+
+def search_from_user_view(columns, where: str, db: DB):
+    if len(where) > 0:
+        where = f"WHERE {where} "
+
+    column = ", ".join(columns)
+    cur = db.search(f"SELECT {column} FROM user_view {where};")
+    if cur is None:
+        return None
+    result = cur.fetchall()
+    re = []
+    for res in result:
+        n = [res[a] for a in range(5)]
+        n.append("True" if res[5] == DBBit.BIT_1 else "False")
+        re.append(n)
+    return re
 
 
 
 
 def find_user_by_id(uid: uid_t, db: DB) -> Optional[User]:
 def find_user_by_id(uid: uid_t, db: DB) -> Optional[User]:
@@ -23,7 +55,7 @@ def find_user_by_id(uid: uid_t, db: DB) -> Optional[User]:
     else:
     else:
         score: score_t = res[3]
         score: score_t = res[3]
         reputation: score_t = res[4]
         reputation: score_t = res[4]
-        rubbish: count_t = countGarbageByTime(uid, db)
+        rubbish: count_t = count_garbage_by_time(uid, db)
         return NormalUser(name, uid, reputation, rubbish, score)  # rubbish 实际计算
         return NormalUser(name, uid, reputation, rubbish, score)  # rubbish 实际计算
 
 
 
 
@@ -62,7 +94,8 @@ def update_user(user: User, db: DB) -> bool:
     return cur is not None
     return cur is not None
 
 
 
 
-def creat_new_user(name: Optional[uname_t], passwd: Optional[passwd_t], phone: phone_t, manager: bool, db: DB) -> Optional[User]:
+def creat_new_user(name: Optional[uname_t], passwd: Optional[passwd_t], phone: phone_t,
+                   manager: bool, db: DB) -> Optional[User]:
     if name is None:
     if name is None:
         name = f'User-{phone[-6:]}'
         name = f'User-{phone[-6:]}'
 
 
@@ -111,7 +144,7 @@ def del_user_from_where_scan(where: str, db: DB) -> int:
 
 
 
 
 def del_user_from_where(where: str, db: DB) -> int:
 def del_user_from_where(where: str, db: DB) -> int:
-    cur = db.search(f"SELECT gid FROM garbage_user WHERE {where};")  # 确保没有引用
+    cur = db.search(f"SELECT gid FROM garbage_time WHERE {where};")  # 确保没有引用
     if cur is None or cur.rowcount != 0:
     if cur is None or cur.rowcount != 0:
         return False
         return False
     cur = db.done(f"DELETE FROM user WHERE {where};")
     cur = db.done(f"DELETE FROM user WHERE {where};")