admin_program.py 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563
  1. import abc
  2. import tkinter as tk
  3. import tkinter.ttk as ttk
  4. from tkinter.filedialog import askdirectory
  5. from tool.type_ import *
  6. from tool.tk import make_font, set_tk_disable_from_list
  7. from tool.login import create_uid
  8. import conf
  9. import admin
  10. import admin_event as tk_event
  11. from sql.user import find_user_by_name
  12. from core.garbage import GarbageType
  13. class AdminProgram(metaclass=abc.ABCMeta):
  14. def __init__(self, station: admin.AdminStation, win: Union[tk.Frame, tk.Toplevel, tk.Tk], color: str, title: str):
  15. self.station = station
  16. self.win = win
  17. self.color = color
  18. self.frame = tk.Frame(self.win)
  19. self.frame['bg'] = color
  20. self.program_title = title
  21. @abc.abstractmethod
  22. def set_disable(self):
  23. ...
  24. @abc.abstractmethod
  25. def reset_disable(self):
  26. ...
  27. @abc.abstractmethod
  28. def conf_gui(self, n: int = 1):
  29. ...
  30. def get_program_frame(self) -> Tuple[str, tk.Frame]:
  31. return self.program_title, self.frame
  32. class WelcomeProgram(AdminProgram):
  33. def __init__(self, station, win, color):
  34. super().__init__(station, win, color, "Welcome")
  35. self.title = tk.Label(self.frame)
  36. self.btn: List[tk.Button] = [tk.Button(self.frame) for _ in range(2)]
  37. self.__conf_font()
  38. def __conf_font(self, n: int = 1):
  39. self.title_font_size = int(25 * n)
  40. self.btn_font_size = int(14 * n)
  41. def conf_gui(self, n: int = 1):
  42. self.__conf_font(n)
  43. title_font = make_font(size=self.title_font_size, weight="bold")
  44. btn_font = make_font(size=self.btn_font_size)
  45. for btn, text in zip(self.btn, ["TestMSG", "TestProgress"]):
  46. btn['font'] = btn_font
  47. btn['text'] = text
  48. btn['bg'] = '#d3d7d4'
  49. self.title['text'] = 'Welcome to HGSSystem Manager'
  50. self.title['font'] = title_font
  51. self.title['bg'] = self.color
  52. self.btn[0]['command'] = lambda: self.test_msg()
  53. self.btn[1]['command'] = lambda: self.test_progress()
  54. self.title.place(relx=0.1, rely=0.3, relwidth=0.8, relheight=0.2)
  55. self.btn[0].place(relx=0.2, rely=0.7, relwidth=0.2, relheight=0.1)
  56. self.btn[1].place(relx=0.6, rely=0.7, relwidth=0.2, relheight=0.1)
  57. def test_progress(self):
  58. event = tk_event.TestProgressEvent(self.station)
  59. self.station.push_event(event)
  60. def test_msg(self):
  61. self.station.show_msg("Test Msg", "test msg")
  62. def set_disable(self):
  63. set_tk_disable_from_list(self.btn)
  64. def reset_disable(self):
  65. set_tk_disable_from_list(self.btn, flat='normal')
  66. class CreateUserProgramBase(AdminProgram):
  67. def __init__(self, station, win, color, title: str):
  68. super().__init__(station, win, color, title)
  69. self.enter_frame = tk.Frame(self.frame)
  70. self.title: List[tk.Label] = [tk.Label(self.enter_frame) for _ in range(3)]
  71. self.enter: List[tk.Entry] = [tk.Entry(self.enter_frame) for _ in range(3)]
  72. self.var: List[tk.Variable] = [tk.StringVar() for _ in range(3)]
  73. self.btn: List[tk.Button] = [tk.Button(self.frame) for _ in range(2)] # create(生成用户) try(计算uid)
  74. self._conf("#FA8072", False) # 默认颜色
  75. self.__conf_font()
  76. def _conf(self, bg_color, is_manager: bool):
  77. self.bg_color = bg_color
  78. self.is_manager = is_manager
  79. return self
  80. def __conf_font(self, n: int = 1):
  81. self.title_font_size = int(16 * n)
  82. self.btn_font_size = int(14 * n)
  83. def conf_gui(self, n: int = 1):
  84. self.__conf_font(n)
  85. title_font = make_font(size=self.title_font_size)
  86. btn_font = make_font(size=self.btn_font_size)
  87. self.enter_frame['bg'] = self.bg_color
  88. self.enter_frame['bd'] = 5
  89. self.enter_frame['relief'] = "ridge"
  90. self.enter_frame.place(relx=0.2, rely=0.3, relwidth=0.6, relheight=0.30)
  91. height = 0.1
  92. for lb, text, enter, var in zip(self.title, ["UserName:", "PassWord:", "Phone:"], self.enter, self.var):
  93. lb['font'] = title_font
  94. lb['text'] = text
  95. lb['bg'] = self.bg_color
  96. lb['anchor'] = 'e'
  97. enter['font'] = title_font
  98. enter['textvariable'] = var
  99. lb.place(relx=0.01, rely=height, relwidth=0.30, relheight=0.17)
  100. enter.place(relx=0.35, rely=height, relwidth=0.60, relheight=0.17)
  101. height += 0.30
  102. for btn, text, x, func in zip(self.btn,
  103. ["Create", "GetUID"],
  104. [0.2, 0.6],
  105. [lambda: self.create_by_name(), lambda: self.get_uid()]):
  106. btn['font'] = btn_font
  107. btn['text'] = text
  108. btn['bg'] = conf.tk_btn_bg
  109. btn['command'] = func
  110. btn.place(relx=x, rely=0.7, relwidth=0.2, relheight=0.08)
  111. def __get_info(self) -> Optional[Tuple[uname_t, passwd_t, str]]:
  112. name: uname_t = self.var[0].get()
  113. passwd: passwd_t = self.var[1].get()
  114. phone: str = self.var[2].get()
  115. if len(name) == 0 or len(passwd) == 0 or len(phone) != 11:
  116. self.station.show_msg("UserInfoError", "Please, enter UserName/Passwd/Phone(11)")
  117. return None
  118. return name, passwd, phone
  119. def create_by_name(self):
  120. res = self.__get_info()
  121. if res is None:
  122. return
  123. name, passwd, phone = res
  124. event = tk_event.CreateUserEvent(self.station).start(name, passwd, phone, self.is_manager)
  125. self.station.push_event(event)
  126. def get_uid(self):
  127. res = self.__get_info()
  128. if res is None:
  129. return
  130. name, passwd, phone = res
  131. uid = create_uid(name, passwd, phone)
  132. self.station.show_msg("UserID", f"UserName: {name}\nUserID: {uid}")
  133. def set_disable(self):
  134. set_tk_disable_from_list(self.btn)
  135. set_tk_disable_from_list(self.enter)
  136. def reset_disable(self):
  137. set_tk_disable_from_list(self.btn, flat='normal')
  138. set_tk_disable_from_list(self.enter, flat='normal')
  139. class CreateNormalUserProgram(CreateUserProgramBase):
  140. def __init__(self, station, win, color):
  141. super(CreateNormalUserProgram, self).__init__(station, win, color, "CreateNormalUser")
  142. class CreateManagerUserProgram(CreateUserProgramBase):
  143. def __init__(self, station, win, color):
  144. super(CreateManagerUserProgram, self).__init__(station, win, color, "CreateManagerUser")
  145. self._conf("#4b5cc4", True)
  146. class CreateAutoNormalUserProgram(AdminProgram):
  147. def __init__(self, station, win, color):
  148. super().__init__(station, win, color, "CreateAutoNormalUser")
  149. self.enter_frame = tk.Frame(self.frame)
  150. self.title: tk.Label = tk.Label(self.enter_frame)
  151. self.enter: tk.Entry = tk.Entry(self.enter_frame)
  152. self.var: tk.Variable = tk.StringVar()
  153. self.btn: tk.Button = tk.Button(self.frame) # create(生成用户) try(计算uid)
  154. self.__conf_font()
  155. def __conf_font(self, n: int = 1):
  156. self.title_font_size = int(16 * n)
  157. self.btn_font_size = int(14 * n)
  158. def conf_gui(self, n: int = 1):
  159. self.__conf_font(n)
  160. title_font = make_font(size=self.title_font_size)
  161. btn_font = make_font(size=self.btn_font_size)
  162. self.enter_frame['bg'] = "#bce672"
  163. self.enter_frame['bd'] = 5
  164. self.enter_frame['relief'] = "ridge"
  165. self.enter_frame.place(relx=0.2, rely=0.3, relwidth=0.6, relheight=0.12)
  166. self.title['font'] = title_font
  167. self.title['text'] = "Phone:"
  168. self.title['bg'] = "#bce672"
  169. self.title['anchor'] = 'e'
  170. self.enter['font'] = title_font
  171. self.enter['textvariable'] = self.var
  172. self.title.place(relx=0.02, rely=0.25, relwidth=0.25, relheight=0.50)
  173. self.enter.place(relx=0.30, rely=0.25, relwidth=0.60, relheight=0.50)
  174. self.btn['font'] = btn_font
  175. self.btn['text'] = "Create"
  176. self.btn['bg'] = conf.tk_btn_bg
  177. self.btn['command'] = lambda: self.create_user()
  178. self.btn.place(relx=0.4, rely=0.7, relwidth=0.2, relheight=0.08)
  179. def create_user(self):
  180. phone = self.var.get()
  181. if len(phone) != 11:
  182. self.station.show_msg("UserInfoError", "Please, enter Phone(11)")
  183. event = tk_event.CreateUserEvent(self.station).start(None, None, phone, False)
  184. self.station.push_event(event)
  185. def set_disable(self):
  186. self.btn['state'] = 'disable'
  187. self.enter['state'] = 'disable'
  188. def reset_disable(self):
  189. self.btn['state'] = 'normal'
  190. self.enter['state'] = 'normal'
  191. class CreateGarbageProgram(AdminProgram):
  192. def __init__(self, station, win, color):
  193. super().__init__(station, win, color, "CreateGarbage")
  194. self.enter_frame = tk.Frame(self.frame)
  195. self.title: List[tk.Label] = [tk.Label(self.enter_frame), tk.Label(self.enter_frame)]
  196. self.enter: List[tk.Entry] = [tk.Entry(self.enter_frame), tk.Entry(self.enter_frame)]
  197. self.var: List[tk.Variable] = [tk.StringVar(), tk.StringVar()]
  198. self.create_btn: tk.Button = tk.Button(self.frame)
  199. self.file_btn: tk.Button = tk.Button(self.frame)
  200. self.__conf_font()
  201. def __conf_font(self, n: int = 1):
  202. self.title_font_size = int(16 * n)
  203. self.btn_font_size = int(14 * n)
  204. def conf_gui(self, n: int = 1):
  205. self.__conf_font(n)
  206. title_font = make_font(size=self.title_font_size)
  207. btn_font = make_font(size=self.btn_font_size)
  208. self.enter_frame['bg'] = "#b69968"
  209. self.enter_frame['bd'] = 5
  210. self.enter_frame['relief'] = "ridge"
  211. self.enter_frame.place(relx=0.2, rely=0.3, relwidth=0.6, relheight=0.17)
  212. height = 0.1
  213. for lb, text, enter, var in zip(self.title, ["Count:", "Export:"], self.enter, self.var):
  214. lb['font'] = title_font
  215. lb['text'] = text
  216. lb['bg'] = "#b69968"
  217. lb['anchor'] = 'e'
  218. enter['font'] = title_font
  219. enter['textvariable'] = var
  220. lb.place(relx=0.01, rely=height, relwidth=0.30, relheight=0.35)
  221. enter.place(relx=0.35, rely=height, relwidth=0.60, relheight=0.35)
  222. height += 0.43
  223. for btn, text, x, func in zip([self.create_btn, self.file_btn],
  224. ["Create", "ChoosePath"],
  225. [0.2, 0.6],
  226. [lambda: self.create_garbage(), lambda: self.choose_file()]):
  227. btn['font'] = btn_font
  228. btn['text'] = text
  229. btn['bg'] = conf.tk_btn_bg
  230. btn['command'] = func
  231. btn.place(relx=x, rely=0.7, relwidth=0.2, relheight=0.08)
  232. def choose_file(self):
  233. path = askdirectory(title='path to save qr code')
  234. self.var[1].set(path)
  235. def create_garbage(self):
  236. try:
  237. count = int(self.var[0].get())
  238. if count <= 0:
  239. raise ValueError
  240. except (ValueError, TypeError):
  241. self.station.show_msg("TypeError", "Count must be number > 1")
  242. else:
  243. path = self.var[1].get()
  244. if len(path) == 0:
  245. path = None
  246. event = tk_event.CreateGarbageEvent(self.station).start(path, count)
  247. self.station.push_event(event)
  248. def set_disable(self):
  249. self.create_btn['state'] = 'disable'
  250. self.file_btn['state'] = 'disable'
  251. set_tk_disable_from_list(self.enter)
  252. def reset_disable(self):
  253. self.create_btn['state'] = 'normal'
  254. self.file_btn['state'] = 'normal'
  255. set_tk_disable_from_list(self.enter, flat='normal')
  256. class ExportProgramBase(AdminProgram):
  257. def __init__(self, station, win, color, title: str):
  258. super().__init__(station, win, color, title)
  259. self.gid_frame = tk.Frame(self.frame)
  260. self.gid_title: List[tk.Label] = [tk.Label(self.gid_frame), tk.Label(self.gid_frame)]
  261. self.gid_enter: List[tk.Entry] = [tk.Entry(self.gid_frame), tk.Entry(self.gid_frame)]
  262. self.gid_var: List[tk.Variable] = [tk.StringVar(), tk.StringVar()]
  263. self.where_frame = tk.Frame(self.frame)
  264. self.where_title: List[tk.Label] = [tk.Label(self.where_frame), tk.Label(self.where_frame)]
  265. self.where_enter: List[tk.Entry] = [tk.Entry(self.where_frame), tk.Entry(self.where_frame)]
  266. self.where_var: List[tk.Variable] = [tk.StringVar(), tk.StringVar()]
  267. self.create_btn: List[tk.Button] = [tk.Button(self.frame), tk.Button(self.frame)]
  268. self.file_btn: List[tk.Button] = [tk.Button(self.frame), tk.Button(self.frame)]
  269. self._conf("", [], [], [])
  270. self.__conf_font()
  271. def _conf(self, bg_color: str, title_id, title_where, title_command):
  272. self.bg_color = bg_color
  273. self.title_id = title_id
  274. self.title_where = title_where
  275. self.title_command = title_command
  276. def __conf_font(self, n: int = 1):
  277. self.title_font_size = int(16 * n)
  278. self.btn_font_size = int(14 * n)
  279. def conf_gui(self, n: int = 1):
  280. self.__conf_font(n)
  281. title_font = make_font(size=self.title_font_size)
  282. btn_font = make_font(size=self.btn_font_size)
  283. self.where_frame['bg'] = self.bg_color
  284. self.where_frame['bd'] = 5
  285. self.where_frame['relief'] = "ridge"
  286. self.where_frame.place(relx=0.2, rely=0.2, relwidth=0.6, relheight=0.17)
  287. self.gid_frame['bg'] = self.bg_color
  288. self.gid_frame['bd'] = 5
  289. self.gid_frame['relief'] = "ridge"
  290. self.gid_frame.place(relx=0.2, rely=0.6, relwidth=0.6, relheight=0.17)
  291. height = 0.1
  292. for lb, text, enter, var, lb_w, text_w, enter_w, var_w in zip(
  293. self.gid_title, self.title_id, self.gid_enter, self.gid_var,
  294. self.where_title, self.title_where, self.where_enter, self.where_var):
  295. lb['font'] = title_font
  296. lb['text'] = text
  297. lb['bg'] = self.bg_color
  298. lb['anchor'] = 'e'
  299. lb_w['font'] = title_font
  300. lb_w['text'] = text_w
  301. lb_w['bg'] = self.bg_color
  302. lb_w['anchor'] = 'e'
  303. enter['textvariable'] = var
  304. enter['font'] = title_font
  305. enter_w['textvariable'] = var_w
  306. enter_w['font'] = title_font
  307. lb.place(relx=0.01, rely=height, relwidth=0.30, relheight=0.35)
  308. enter.place(relx=0.35, rely=height, relwidth=0.60, relheight=0.35)
  309. lb_w.place(relx=0.01, rely=height, relwidth=0.30, relheight=0.35)
  310. enter_w.place(relx=0.35, rely=height, relwidth=0.60, relheight=0.35)
  311. height += 0.43
  312. for btn, text in zip(self.create_btn + self.file_btn, self.title_command):
  313. btn['font'] = btn_font
  314. btn['text'] = text
  315. btn['bg'] = conf.tk_btn_bg
  316. self.create_btn[1]['command'] = self.export_where
  317. self.create_btn[0]['command'] = self.export_id
  318. self.create_btn[1].place(relx=0.2, rely=0.39, relwidth=0.25, relheight=0.08)
  319. self.create_btn[0].place(relx=0.2, rely=0.79, relwidth=0.25, relheight=0.08)
  320. self.file_btn[1]['command'] = self.choose_file_where
  321. self.file_btn[0]['command'] = self.choose_file_id
  322. self.file_btn[1].place(relx=0.6, rely=0.39, relwidth=0.2, relheight=0.08)
  323. self.file_btn[0].place(relx=0.6, rely=0.79, relwidth=0.2, relheight=0.08)
  324. def choose_file_id(self):
  325. path = askdirectory(title='path to save qr code')
  326. self.gid_var[1].set(path)
  327. def choose_file_where(self):
  328. path = askdirectory(title='path to save qr code')
  329. self.where_var[1].set(path)
  330. def export_id(self):
  331. ...
  332. def export_where(self):
  333. ...
  334. def set_disable(self):
  335. set_tk_disable_from_list(self.gid_enter)
  336. set_tk_disable_from_list(self.create_btn)
  337. set_tk_disable_from_list(self.file_btn)
  338. def reset_disable(self):
  339. set_tk_disable_from_list(self.gid_enter, flat='normal')
  340. set_tk_disable_from_list(self.create_btn, flat='normal')
  341. set_tk_disable_from_list(self.file_btn, flat='normal')
  342. class ExportGarbageProgram(ExportProgramBase):
  343. def __init__(self, station, win, color):
  344. super().__init__(station, win, color, "ExportGarbage")
  345. self._conf("#afdfe4", ["GarbageID:", "Export:"], ["Where:", "Export:"],
  346. ["Export By GarbageID", "Export Advanced", "ChoosePath", "ChoosePath"])
  347. def export_id(self):
  348. gid = self.gid_var[0].get()
  349. path = self.gid_var[1].get()
  350. event = tk_event.ExportGarbageByIDEvent(self.station).start(path, gid)
  351. self.station.push_event(event)
  352. def export_where(self):
  353. where = self.where_var[0].get()
  354. path = self.where_var[1].get()
  355. event = tk_event.ExportGarbageAdvancedEvent(self.station).start(path, where)
  356. self.station.push_event(event)
  357. class ExportUserProgram(ExportProgramBase):
  358. def __init__(self, station, win, color):
  359. super().__init__(station, win, color, "ExportUser")
  360. self._conf("#f69c9f", ["UserID:", "Export:"], ["Where:", "Export:"],
  361. ["Export By UserID", "Export Advanced", "ChoosePath", "ChoosePath"])
  362. def export_id(self):
  363. uid = self.gid_var[0].get()
  364. path = self.gid_var[1].get()
  365. event = tk_event.ExportUserByIDEvent(self.station).start(path, uid)
  366. self.station.push_event(event)
  367. def export_where(self):
  368. where = self.where_var[0].get()
  369. path = self.where_var[1].get()
  370. event = tk_event.ExportUserAdvancedEvent(self.station).start(path, where)
  371. self.station.push_event(event)
  372. class DeleteUserProgram(AdminProgram):
  373. def __init__(self, station, win, color):
  374. super().__init__(station, win, color, "DeleteUser")
  375. self.uid_frame = tk.Frame(self.frame)
  376. self.uid_title: tk.Label = tk.Label(self.uid_frame)
  377. self.uid_enter: tk.Entry = tk.Entry(self.uid_frame)
  378. self.uid_var: tk.Variable = tk.StringVar()
  379. self.name_frame = tk.Frame(self.frame)
  380. self.name_title: List[tk.Label] = [tk.Label(self.name_frame) for _ in range(2)]
  381. self.name_enter: List[tk.Entry] = [tk.Entry(self.name_frame) for _ in range(2)]
  382. self.name_var: List[tk.Variable] = [tk.StringVar() for _ in range(2)]
  383. self.btn: List[tk.Button] = [tk.Button(self.frame) for _ in range(2)] # uid-del, name-passwd-del
  384. self.__conf_font()
  385. def __conf_font(self, n: int = 1):
  386. self.title_font_size = int(16 * n)
  387. self.btn_font_size = int(14 * n)
  388. def conf_gui(self, n: int = 1):
  389. self.__conf_font(n)
  390. title_font = make_font(size=self.title_font_size)
  391. btn_font = make_font(size=self.btn_font_size)
  392. self.uid_frame['bg'] = "#FA8072"
  393. self.uid_frame['bd'] = 5
  394. self.uid_frame['relief'] = "ridge"
  395. self.uid_frame.place(relx=0.2, rely=0.20, relwidth=0.6, relheight=0.10)
  396. self.name_frame['bg'] = "#FA8072"
  397. self.name_frame['bd'] = 5
  398. self.name_frame['relief'] = "ridge"
  399. self.name_frame.place(relx=0.2, rely=0.48, relwidth=0.6, relheight=0.25)
  400. height = 0.17
  401. for lb, text, enter, var in zip(self.name_title, ["UserName:", "PassWord:"], self.name_enter, self.name_var):
  402. lb['font'] = title_font
  403. lb['text'] = text
  404. lb['bg'] = "#FA8072"
  405. lb['anchor'] = 'e'
  406. enter['font'] = title_font
  407. enter['textvariable'] = var
  408. lb.place(relx=0.01, rely=height, relwidth=0.30, relheight=0.20)
  409. enter.place(relx=0.35, rely=height, relwidth=0.60, relheight=0.20)
  410. height += 0.45
  411. self.uid_title['font'] = title_font
  412. self.uid_title['text'] = "UserID:"
  413. self.uid_title['bg'] = "#FA8072"
  414. self.uid_title['anchor'] = 'e'
  415. self.uid_enter['font'] = title_font
  416. self.uid_enter['textvariable'] = self.uid_var
  417. self.uid_title.place(relx=0.01, rely=0.25, relwidth=0.30, relheight=0.50)
  418. self.uid_enter.place(relx=0.35, rely=0.25, relwidth=0.60, relheight=0.50)
  419. for btn, text, func in zip(self.btn,
  420. ["Delete By Uid", "Delete By Name"],
  421. [lambda: self.del_by_uid(), lambda: self.del_by_name()]):
  422. btn['font'] = btn_font
  423. btn['text'] = text
  424. btn['bg'] = conf.tk_btn_bg
  425. btn['command'] = func
  426. self.btn[0].place(relx=0.6, rely=0.32, relwidth=0.2, relheight=0.08)
  427. self.btn[1].place(relx=0.6, rely=0.75, relwidth=0.2, relheight=0.08)
  428. def del_by_uid(self):
  429. uid = self.uid_var.get()
  430. if len(uid) != 32:
  431. self.station.show_msg("UserID Error", "Len of UserID must be 32", "Error")
  432. return
  433. event = tk_event.DelUserEvent(self.station).start(uid)
  434. self.station.push_event(event)
  435. def del_by_name(self):
  436. name = self.name_var[0].get()
  437. passwd = self.name_var[1].get()
  438. if len(name) == 0 or len(passwd) == 0:
  439. self.station.show_msg("UserName/Password Error", "You should enter UserName and Password", "Error")
  440. return
  441. uid = create_uid(name, passwd)
  442. event = tk_event.DelUserEvent(self.station).start(uid)
  443. self.station.push_event(event)
  444. def set_disable(self):
  445. set_tk_disable_from_list(self.btn)
  446. set_tk_disable_from_list(self.name_enter)
  447. self.uid_enter['state'] = 'disable'
  448. def reset_disable(self):
  449. set_tk_disable_from_list(self.btn, flat='normal')
  450. set_tk_disable_from_list(self.name_enter, flat='normal')
  451. self.uid_enter['state'] = 'normal'
  452. class DeleteUsersProgram(AdminProgram):
  453. def __init__(self, station, win, color):
  454. super().__init__(station, win, color, "DeleteUsers")
  455. self.enter_frame = tk.Frame(self.frame)
  456. self.title: tk.Label = tk.Label(self.enter_frame)
  457. self.enter: tk.Entry = tk.Entry(self.enter_frame)
  458. self.var: tk.Variable = tk.StringVar()
  459. self.btn: List[tk.Button] = [tk.Button(self.frame) for _ in range(2)] # del, scan
  460. self.__conf_font()
  461. def __conf_font(self, n: int = 1):
  462. self.title_font_size = int(16 * n)
  463. self.btn_font_size = int(14 * n)
  464. def conf_gui(self, n: int = 1):
  465. self.__conf_font(n)
  466. title_font = make_font(size=self.title_font_size)
  467. btn_font = make_font(size=self.btn_font_size)
  468. self.enter_frame['bg'] = "#48c0a3"
  469. self.enter_frame['bd'] = 5
  470. self.enter_frame['relief'] = "ridge"
  471. self.enter_frame.place(relx=0.2, rely=0.30, relwidth=0.6, relheight=0.10)
  472. self.title['font'] = title_font
  473. self.title['text'] = "Where:"
  474. self.title['anchor'] = 'e'
  475. self.title['bg'] = "#48c0a3"
  476. self.enter['font'] = title_font
  477. self.enter['textvariable'] = self.var
  478. self.title.place(relx=0.01, rely=0.25, relwidth=0.30, relheight=0.50)
  479. self.enter.place(relx=0.35, rely=0.25, relwidth=0.60, relheight=0.50)
  480. for btn, text, x, func in zip(self.btn,
  481. ["Delete", "Scan"],
  482. [0.2, 0.6],
  483. [lambda: self.delete_user(), lambda: self.scan_user()]):
  484. btn['font'] = btn_font
  485. btn['text'] = text
  486. btn['bg'] = conf.tk_btn_bg
  487. btn['command'] = func
  488. btn.place(relx=x, rely=0.6, relwidth=0.2, relheight=0.08)
  489. def delete_user(self):
  490. where = self.var.get()
  491. if len(where) == 0:
  492. self.station.show_msg("`Where`Error", "`Where` must be SQL", "Warning")
  493. return
  494. event = tk_event.DelUserFromWhereEvent(self.station).start(where)
  495. self.station.push_event(event)
  496. def scan_user(self):
  497. where = self.var.get()
  498. if len(where) == 0:
  499. self.station.show_msg("`Where`Error", "`Where` must be SQL", "Warning")
  500. return
  501. event = tk_event.DelUserFromWhereScanEvent(self.station).start(where)
  502. self.station.push_event(event)
  503. def set_disable(self):
  504. set_tk_disable_from_list(self.btn)
  505. self.enter['state'] = 'disable'
  506. def reset_disable(self):
  507. set_tk_disable_from_list(self.btn, flat='normal')
  508. self.enter['state'] = 'normal'
  509. class DeleteGarbageProgramBase(AdminProgram):
  510. def __init__(self, station, win, color, title: str):
  511. super().__init__(station, win, color, title)
  512. self.enter_frame = tk.Frame(self.frame)
  513. self.title: tk.Label = tk.Label(self.enter_frame)
  514. self.enter: tk.Entry = tk.Entry(self.enter_frame)
  515. self.var: tk.Variable = tk.StringVar()
  516. self.int_var: tk.Variable = tk.IntVar()
  517. self.int_var.set(0)
  518. self.radio: List[tk.Radiobutton] = [tk.Radiobutton(self.frame) for _ in range(4)]
  519. self.btn: tk.Button = tk.Button(self.frame)
  520. self.__conf_font()
  521. self._conf()
  522. def _conf(self, title: str = "GarbageID:", color: str = "#b69968", support_del_all: bool = True):
  523. self.frame_title = title
  524. self.frame_color = color
  525. self.support_del_all = support_del_all
  526. def __conf_font(self, n: int = 1):
  527. self.title_font_size = int(16 * n)
  528. self.btn_font_size = int(14 * n)
  529. def conf_gui(self, n: int = 1):
  530. self.__conf_font(n)
  531. title_font = make_font(size=self.title_font_size)
  532. btn_font = make_font(size=self.btn_font_size)
  533. self.enter_frame['bg'] = self.frame_color
  534. self.enter_frame['bd'] = 5
  535. self.enter_frame['relief'] = "ridge"
  536. self.enter_frame.place(relx=0.2, rely=0.30, relwidth=0.6, relheight=0.10)
  537. self.title['font'] = title_font
  538. self.title['text'] = self.frame_title
  539. self.title['bg'] = self.frame_color
  540. self.title['anchor'] = 'e'
  541. self.enter['font'] = title_font
  542. self.enter['textvariable'] = self.var
  543. self.title.place(relx=0.01, rely=0.25, relwidth=0.30, relheight=0.50)
  544. self.enter.place(relx=0.35, rely=0.25, relwidth=0.60, relheight=0.50)
  545. for i in range(4):
  546. radio = self.radio[i]
  547. radio['font'] = btn_font
  548. radio['text'] = ['From-All', 'From-NotUse', 'From-Waiting', 'From-Used'][i]
  549. radio['bg'] = self.color
  550. radio['value'] = i
  551. radio['variable'] = self.int_var
  552. radio['anchor'] = 'w'
  553. if not self.support_del_all:
  554. self.int_var.set(1)
  555. self.radio[0]['state'] = 'disable'
  556. self.radio[0].place(relx=0.20, rely=0.43, relwidth=0.20, relheight=0.1)
  557. self.radio[1].place(relx=0.60, rely=0.43, relwidth=0.20, relheight=0.1)
  558. self.radio[2].place(relx=0.20, rely=0.55, relwidth=0.20, relheight=0.1)
  559. self.radio[3].place(relx=0.60, rely=0.55, relwidth=0.20, relheight=0.1)
  560. self.btn['font'] = btn_font
  561. self.btn['text'] = 'Delete'
  562. self.btn['bg'] = conf.tk_btn_bg
  563. self.btn['command'] = lambda: self.delete_garbage()
  564. self.btn.place(relx=0.4, rely=0.68, relwidth=0.2, relheight=0.08)
  565. def delete_garbage(self):
  566. ...
  567. def set_disable(self):
  568. self.enter['state'] = 'disable'
  569. self.btn['state'] = 'disable'
  570. def reset_disable(self):
  571. self.enter['state'] = 'normal'
  572. self.btn['state'] = 'normal'
  573. class DeleteGarbageProgram(DeleteGarbageProgramBase):
  574. def __init__(self, station, win, color):
  575. super(DeleteGarbageProgram, self).__init__(station, win, color, "DeleteGarbage")
  576. def delete_garbage(self):
  577. where = self.int_var.get()
  578. assert where in [0, 1, 2, 3]
  579. gid = self.var.get()
  580. if len(gid) == 0:
  581. self.station.show_msg("GarbageID Error", "You should enter the garbage id", "Warning")
  582. return
  583. event = tk_event.DelGarbageEvent(self.station).start(gid, where)
  584. self.station.push_event(event)
  585. class DeleteGarbageMoreProgram(DeleteGarbageProgramBase):
  586. def __init__(self, station, win, color):
  587. super(DeleteGarbageMoreProgram, self).__init__(station, win, color, "DeleteGarbageMore")
  588. self.scan_btn = tk.Button(self.frame)
  589. self._conf("Where:", "#f58f98", False)
  590. def conf_gui(self, n: int = 1):
  591. super(DeleteGarbageMoreProgram, self).conf_gui(n)
  592. self.btn.place_forget()
  593. self.btn.place(relx=0.2, rely=0.68, relwidth=0.2, relheight=0.08)
  594. self.scan_btn['font'] = make_font(size=self.btn_font_size)
  595. self.scan_btn['text'] = 'Scan'
  596. self.scan_btn['bg'] = conf.tk_btn_bg
  597. self.scan_btn['command'] = lambda: self.delete_garbage(True)
  598. self.scan_btn.place(relx=0.6, rely=0.68, relwidth=0.2, relheight=0.08)
  599. def set_disable(self):
  600. super(DeleteGarbageMoreProgram, self).set_disable()
  601. self.scan_btn['state'] = 'disable'
  602. def reset_disable(self):
  603. super(DeleteGarbageMoreProgram, self).reset_disable()
  604. self.scan_btn['state'] = 'normal'
  605. def delete_garbage(self, is_scan: bool = False):
  606. where = self.int_var.get()
  607. assert where in [1, 2, 3]
  608. where_sql = self.var.get()
  609. if len(where_sql) == 0:
  610. self.station.show_msg("`Where`Error", "`Where` must be SQL", "Warning")
  611. return
  612. if is_scan:
  613. event = tk_event.DelGarbageWhereScanEvent(self.station).start(where, where_sql)
  614. else:
  615. event = tk_event.DelGarbageWhereEvent(self.station).start(where, where_sql)
  616. self.station.push_event(event)
  617. class DeleteAllGarbageProgram(AdminProgram):
  618. def __init__(self, station, win, color):
  619. super().__init__(station, win, color, "DeleteAllGarbage")
  620. self.dangerous: tk.Label = tk.Label(self.frame)
  621. self.enter_frame = tk.Frame(self.frame)
  622. self.title: tk.Label = tk.Label(self.enter_frame)
  623. self.enter: tk.Entry = tk.Entry(self.enter_frame)
  624. self.var: tk.Variable = tk.StringVar()
  625. self.btn: List[tk.Button] = [tk.Button(self.frame) for _ in range(2)] # del, scan
  626. self.__conf_font()
  627. def __conf_font(self, n: int = 1):
  628. self.danger_font_size = int(20 * n)
  629. self.title_font_size = int(16 * n)
  630. self.btn_font_size = int(14 * n)
  631. def conf_gui(self, n: int = 1):
  632. self.__conf_font(n)
  633. danger_font = make_font(size=self.danger_font_size, weight="bold", underline=1)
  634. title_font = make_font(size=self.title_font_size)
  635. btn_font = make_font(size=self.btn_font_size)
  636. danger_btn_font = make_font(size=self.btn_font_size, weight="bold", overstrike=1)
  637. self.dangerous['bg'] = self.color
  638. self.dangerous['font'] = danger_font
  639. self.dangerous['fg'] = "#f20c00"
  640. self.dangerous['text'] = ("Delete all garbage from database?\n"
  641. "Please enter the admin-passwd to\n"
  642. "continue.\n"
  643. "Dangerous operation.\n"
  644. "The database may not be restored.\n"
  645. "SuperHuan is not responsible for\n"
  646. "the consequences.")
  647. self.dangerous.place(relx=0.05, rely=0.03, relwidth=0.9, relheight=0.43)
  648. self.enter_frame['bg'] = "#f20c00"
  649. self.enter_frame['bd'] = 5
  650. self.enter_frame['relief'] = "ridge"
  651. self.enter_frame.place(relx=0.2, rely=0.50, relwidth=0.6, relheight=0.10)
  652. self.title['font'] = title_font
  653. self.title['text'] = "Password:"
  654. self.title['bg'] = "#f20c00"
  655. self.title['anchor'] = 'e'
  656. self.enter['font'] = title_font
  657. self.enter['textvariable'] = self.var
  658. self.title.place(relx=0.01, rely=0.25, relwidth=0.30, relheight=0.50)
  659. self.enter.place(relx=0.35, rely=0.25, relwidth=0.60, relheight=0.50)
  660. for btn, text, x in zip(self.btn, ["Delete", "Scan"], [0.2, 0.6]):
  661. btn['text'] = text
  662. btn.place(relx=x, rely=0.68, relwidth=0.2, relheight=0.08)
  663. self.btn[0]['font'] = danger_btn_font
  664. self.btn[0]['bg'] = "#f20c00"
  665. self.btn[0]['command'] = lambda: self.delete_garbage()
  666. self.btn[1]['font'] = btn_font
  667. self.btn[1]['bg'] = conf.tk_btn_bg
  668. self.btn[1]['command'] = lambda: self.scan_garbage()
  669. def scan_garbage(self):
  670. event = tk_event.DelAllGarbageScanEvent(self.station) # 不需要start
  671. self.station.push_event(event)
  672. def delete_garbage(self):
  673. passwd = self.var.get()
  674. if len(passwd) == 0:
  675. self.station.show_msg("PassWordError", "Password error", "Warning")
  676. user = find_user_by_name('admin', passwd, self.station.get_db())
  677. if user is None or not user.is_manager():
  678. self.station.show_msg("PassWordError", "Password error", "Warning")
  679. return
  680. event = tk_event.DelAllGarbageEvent(self.station) # 不需要start
  681. self.station.push_event(event)
  682. def set_disable(self):
  683. set_tk_disable_from_list(self.btn)
  684. self.enter['state'] = 'disable'
  685. def reset_disable(self):
  686. set_tk_disable_from_list(self.btn, flat='normal')
  687. self.enter['state'] = 'normal'
  688. class SearchBaseProgram(AdminProgram, metaclass=abc.ABCMeta):
  689. def __init__(self, station, win, color, title: str):
  690. super().__init__(station, win, color, title)
  691. self.view_frame = tk.Frame(self.frame)
  692. self.view = ttk.Treeview(self.view_frame)
  693. self.y_scroll = tk.Scrollbar(self.view_frame)
  694. self.x_scroll = tk.Scrollbar(self.view_frame)
  695. def conf_view_gui(self, columns: list, relx, rely, relwidth, relheight,
  696. x_scroll=0.05, y_scroll=0.02, color: str = "#FA8072"):
  697. self.view_frame['bg'] = color
  698. self.view_frame['bd'] = 2
  699. self.view_frame['relief'] = "ridge"
  700. self.view_frame.place(relx=relx, rely=rely, relwidth=relwidth, relheight=relheight)
  701. self.view['columns'] = columns
  702. self.view['show'] = 'headings'
  703. self.view['selectmode'] = 'none'
  704. for i in columns:
  705. self.view.column(i, anchor="c")
  706. self.view.heading(i, text=i)
  707. self.y_scroll['orient'] = 'vertical'
  708. self.y_scroll['command'] = self.view.yview
  709. self.view['yscrollcommand'] = self.y_scroll.set
  710. self.x_scroll['orient'] = 'horizontal'
  711. self.x_scroll['command'] = self.view.xview
  712. self.view['xscrollcommand'] = self.x_scroll.set
  713. self.view.place(relx=0.0, rely=0.0, relwidth=1 - y_scroll, relheight=1 - x_scroll)
  714. self.y_scroll.place(relx=0.98, rely=0.0, relwidth=y_scroll, relheight=1.0)
  715. self.x_scroll.place(relx=0.0, rely=1 - x_scroll, relwidth=1 - y_scroll, relheight=x_scroll)
  716. class SearchUserProgram(SearchBaseProgram):
  717. def __init__(self, station, win, color):
  718. super().__init__(station, win, color, "SearchUser")
  719. self.enter_frame = tk.Frame(self.frame)
  720. self.title: List[tk.Label] = [tk.Label(self.enter_frame) for _ in range(3)]
  721. self.enter: List[tk.Entry] = [tk.Entry(self.enter_frame) for _ in range(3)]
  722. self.var: List[tk.Variable] = [tk.StringVar() for _ in range(3)]
  723. self.check: List[Tuple[tk.Checkbutton, tk.Variable]] = [(tk.Checkbutton(self.enter_frame), tk.IntVar())
  724. for _ in range(3)]
  725. self.btn: tk.Button = tk.Button(self.frame)
  726. self._columns = ["UserID", "Name", "Phone", "Score", "Reputation", "IsManager"]
  727. self.__conf_font()
  728. def __conf_font(self, n: int = 1):
  729. self.title_font_size = int(16 * n)
  730. self.btn_font_size = int(14 * n)
  731. def conf_gui(self, n: int = 1):
  732. self.__conf_font(n)
  733. title_font = make_font(size=self.title_font_size)
  734. btn_font = make_font(size=self.btn_font_size)
  735. self.enter_frame['bg'] = "#FA8072"
  736. self.enter_frame['bd'] = 5
  737. self.enter_frame['relief'] = "ridge"
  738. self.enter_frame.place(relx=0.2, rely=0.0, relwidth=0.6, relheight=0.30)
  739. height = 0.1
  740. for lb, text, enter, var, check in zip(self.title,
  741. ["UserID:", "UserName:", "Phone:"],
  742. self.enter, self.var, self.check):
  743. lb['font'] = title_font
  744. lb['text'] = text
  745. lb['bg'] = "#FA8072"
  746. lb['anchor'] = 'e'
  747. enter['font'] = title_font
  748. enter['textvariable'] = var
  749. check[0]['font'] = title_font
  750. check[0]['text'] = ''
  751. check[0]['bg'] = "#FA8072"
  752. check[0]['variable'] = check[1]
  753. check[1].set(1)
  754. lb.place(relx=0.01, rely=height, relwidth=0.30, relheight=0.17)
  755. enter.place(relx=0.35, rely=height, relwidth=0.55, relheight=0.17)
  756. check[0].place(relx=0.92, rely=height, relwidth=0.04, relheight=0.17)
  757. height += 0.30
  758. self.btn['font'] = btn_font
  759. self.btn['text'] = "Search"
  760. self.btn['bg'] = conf.tk_btn_bg
  761. self.btn['command'] = self.search_user
  762. self.btn.place(relx=0.4, rely=0.9, relwidth=0.2, relheight=0.08)
  763. self.conf_view_gui(self._columns, relx=0.05, rely=0.32, relwidth=0.9, relheight=0.55)
  764. def search_user(self):
  765. use_uid = self.check[0][1].get()
  766. use_name = self.check[1][1].get()
  767. use_phone = self.check[2][1].get()
  768. uid = None
  769. name = None
  770. phone = None
  771. if use_uid:
  772. uid = self.var[0].get()
  773. if len(uid) == 0:
  774. uid = None
  775. if use_name:
  776. name = self.var[1].get()
  777. if len(name) == 0:
  778. name = None
  779. if use_phone:
  780. phone = self.var[2].get()
  781. if len(phone) == 0:
  782. phone = None
  783. event = tk_event.SearchUserEvent(self.station).start(self._columns, uid, name, phone, self)
  784. self.station.push_event(event)
  785. def set_disable(self):
  786. self.btn['state'] = 'disable'
  787. set_tk_disable_from_list(self.enter)
  788. def reset_disable(self):
  789. self.btn['state'] = 'normal'
  790. set_tk_disable_from_list(self.enter, flat='normal')
  791. class SearchAdvancedProgramBase(SearchBaseProgram, metaclass=abc.ABCMeta):
  792. def __init__(self, station, win, color, title: str):
  793. super().__init__(station, win, color, title)
  794. self.enter_frame = tk.Frame(self.frame)
  795. self.title: tk.Label = tk.Label(self.enter_frame)
  796. self.enter: tk.Entry = tk.Entry(self.enter_frame)
  797. self.var: tk.Variable = tk.StringVar()
  798. self.btn: tk.Button = tk.Button(self.frame)
  799. self._conf([], "#FA8072") # 默认颜色
  800. self.__conf_font()
  801. def _conf(self, columns: list, bg_color):
  802. self.bg_color = bg_color
  803. self._columns = columns
  804. return self
  805. def __conf_font(self, n: int = 1):
  806. self.title_font_size = int(16 * n)
  807. self.btn_font_size = int(14 * n)
  808. def conf_gui(self, n: int = 1):
  809. self.__conf_font(n)
  810. title_font = make_font(size=self.title_font_size)
  811. btn_font = make_font(size=self.btn_font_size)
  812. self.enter_frame['bg'] = self.bg_color
  813. self.enter_frame['bd'] = 5
  814. self.enter_frame['relief'] = "ridge"
  815. self.enter_frame.place(relx=0.2, rely=0.00, relwidth=0.6, relheight=0.10)
  816. self.title['font'] = title_font
  817. self.title['bg'] = self.bg_color
  818. self.title['text'] = "Where:"
  819. self.title['anchor'] = 'e'
  820. self.enter['font'] = title_font
  821. self.enter['textvariable'] = self.var
  822. self.title.place(relx=0.01, rely=0.25, relwidth=0.30, relheight=0.50)
  823. self.enter.place(relx=0.35, rely=0.25, relwidth=0.60, relheight=0.50)
  824. self.btn['text'] = "Search"
  825. self.btn['font'] = btn_font
  826. self.btn['bg'] = conf.tk_btn_bg
  827. self.btn['command'] = self.search
  828. self.btn.place(relx=0.4, rely=0.9, relwidth=0.2, relheight=0.08)
  829. self.conf_view_gui(self._columns, relx=0.05, rely=0.12, relwidth=0.9, relheight=0.76)
  830. def search(self):
  831. ...
  832. def set_disable(self):
  833. self.btn['state'] = 'disable'
  834. self.enter['state'] = 'disable'
  835. def reset_disable(self):
  836. self.btn['state'] = 'normal'
  837. self.enter['state'] = 'normal'
  838. class SearchUserAdvancedProgram(SearchAdvancedProgramBase):
  839. def __init__(self, station, win, color):
  840. super(SearchUserAdvancedProgram, self).__init__(station, win, color, "SearchUserAdvanced")
  841. columns = ["UserID", "Name", "Phone", "Score", "Reputation", "IsManager"]
  842. self._conf(columns, '#48c0a3')
  843. def search(self):
  844. where = self.var.get()
  845. event = tk_event.SearchUserAdvancedEvent(self.station).start(self._columns, where, self)
  846. self.station.push_event(event)
  847. class SearchGarbageProgram(SearchBaseProgram):
  848. def __init__(self, station, win, color):
  849. super().__init__(station, win, color, "SearchGarbage")
  850. self.enter_frame = tk.Frame(self.frame)
  851. self.title: List[tk.Label] = [tk.Label(self.enter_frame) for _ in range(8)]
  852. self.enter: List[tk.Entry] = [tk.Entry(self.enter_frame) for _ in range(8)]
  853. self.var: List[tk.Variable] = [tk.StringVar() for _ in range(8)]
  854. self.check: List[Tuple[tk.Checkbutton, tk.Variable]] = [(tk.Checkbutton(self.enter_frame), tk.IntVar())
  855. for _ in range(8)]
  856. self._columns = ["GarbageID", "UserID", "CheckerID", "CreateTime", "UseTime", "Location", "GarbageType",
  857. "CheckResult"]
  858. self.btn: tk.Button = tk.Button(self.frame)
  859. self.__conf_font()
  860. def __conf_font(self, n: int = 1):
  861. self.title_font_size = int(16 * n)
  862. self.btn_font_size = int(14 * n)
  863. def conf_gui(self, n: int = 1):
  864. self.__conf_font(n)
  865. title_font = make_font(size=self.title_font_size)
  866. btn_font = make_font(size=self.btn_font_size)
  867. self.enter_frame['bg'] = "#7bbfea"
  868. self.enter_frame['bd'] = 5
  869. self.enter_frame['relief'] = "ridge"
  870. self.enter_frame.place(relx=0.2, rely=0.0, relwidth=0.6, relheight=0.47)
  871. height = 0.02
  872. for lb, text, enter, var, check in zip(self.title,
  873. ["GarbageID:", "UserID:", "CheckerID:", "CreateTime:", "UseTime:",
  874. "Location:", "GarbageType:", "CheckResult:"],
  875. self.enter, self.var, self.check):
  876. lb['font'] = title_font
  877. lb['text'] = text
  878. lb['bg'] = "#7bbfea"
  879. lb['anchor'] = 'e'
  880. enter['font'] = title_font
  881. enter['textvariable'] = var
  882. check[0]['font'] = title_font
  883. check[0]['bg'] = "#7bbfea"
  884. check[0]['text'] = ''
  885. check[0]['variable'] = check[1]
  886. check[1].set(1)
  887. lb.place(relx=0.01, rely=height, relwidth=0.30, relheight=0.10)
  888. enter.place(relx=0.35, rely=height, relwidth=0.55, relheight=0.10)
  889. check[0].place(relx=0.92, rely=height, relwidth=0.04, relheight=0.10)
  890. height += 0.121
  891. self.btn['font'] = btn_font
  892. self.btn['bg'] = conf.tk_btn_bg
  893. self.btn['text'] = "Search"
  894. self.btn['command'] = self.search_user
  895. self.btn.place(relx=0.4, rely=0.9, relwidth=0.2, relheight=0.08)
  896. self.conf_view_gui(self._columns, relx=0.05, rely=0.49, relwidth=0.9, relheight=0.38, x_scroll=0.07)
  897. def search_user(self):
  898. keys = ["gid", "uid", "cuid", "create_time", "use_time", "loc", "type_", "check"]
  899. key_values = {}
  900. for i, key in enumerate(keys):
  901. ck = self.check[i][1].get()
  902. if ck:
  903. res = self.enter[i].get()
  904. if len(res) > 0:
  905. key_values[key] = res
  906. continue
  907. key_values[key] = None
  908. event = tk_event.SearchGarbageEvent(self.station).start(self._columns, key_values, self)
  909. self.station.push_event(event)
  910. def set_disable(self):
  911. self.btn['state'] = 'disable'
  912. set_tk_disable_from_list(self.enter)
  913. def reset_disable(self):
  914. self.btn['state'] = 'normal'
  915. set_tk_disable_from_list(self.enter, flat='normal')
  916. class SearchGarbageAdvancedProgram(SearchAdvancedProgramBase):
  917. def __init__(self, station, win, color):
  918. super(SearchGarbageAdvancedProgram, self).__init__(station, win, color, "SearchGarbageAdvanced")
  919. columns = ["GarbageID", "UserID", "CheckerID", "CreateTime", "UseTime", "Location", "GarbageType",
  920. "CheckResult"]
  921. self._conf(columns, '#d1923f')
  922. def search(self):
  923. where = self.var.get()
  924. event = tk_event.SearchGarbageAdvancedEvent(self.station).start(self._columns, where, self)
  925. self.station.push_event(event)
  926. class SearchAdvancedProgram(SearchAdvancedProgramBase):
  927. def __init__(self, station, win, color):
  928. super(SearchAdvancedProgram, self).__init__(station, win, color, "SearchAdvanced")
  929. columns = ["GarbageID", "UserID", "UserName", "UserPhone", "UserScore",
  930. "UserReputation", "CheckerID", "CheckerName", "CheckerPhone",
  931. "CreateTime", "UseTime", "Location", "GarbageType", "CheckResult"]
  932. self._conf(columns, '#426ab3')
  933. def search(self):
  934. where = self.var.get()
  935. event = tk_event.SearchAdvancedEvent(self.station).start(self._columns, where, self)
  936. self.station.push_event(event)
  937. class UpdateUserProgramBase(AdminProgram):
  938. def __init__(self, station, win, color, title: str):
  939. super().__init__(station, win, color, title)
  940. self.enter_frame = tk.Frame(self.frame)
  941. self.title: List[tk.Label] = [tk.Label(self.enter_frame) for _ in range(2)]
  942. self.enter: List[tk.Entry] = [tk.Entry(self.enter_frame) for _ in range(2)]
  943. self.var: List[tk.Variable] = [tk.StringVar() for _ in range(2)]
  944. self.where_frame = tk.Frame(self.frame)
  945. self.where_title: List[tk.Label] = [tk.Label(self.where_frame) for _ in range(2)]
  946. self.where_enter: List[tk.Entry] = [tk.Entry(self.where_frame) for _ in range(2)]
  947. self.where_var: List[tk.Variable] = [tk.StringVar() for _ in range(2)]
  948. self.btn: List[tk.Button] = [tk.Button(self.frame), tk.Button(self.frame)]
  949. self._conf(["", ""], "#FA8072")
  950. self.__conf_font()
  951. def _conf(self, title: List[str], bg_color: str):
  952. self.bg_color = bg_color
  953. self.bg_color_where = bg_color
  954. self.enter_title = title
  955. def __conf_font(self, n: int = 1):
  956. self.title_font_size = int(16 * n)
  957. self.btn_font_size = int(14 * n)
  958. def conf_gui(self, n: int = 1):
  959. self.__conf_font(n)
  960. title_font = make_font(size=self.title_font_size)
  961. btn_font = make_font(size=self.btn_font_size)
  962. self.where_frame['bg'] = self.bg_color_where
  963. self.where_frame['bd'] = 5
  964. self.where_frame['relief'] = "ridge"
  965. self.where_frame.place(relx=0.2, rely=0.20, relwidth=0.6, relheight=0.17)
  966. self.enter_frame['bg'] = self.bg_color
  967. self.enter_frame['bd'] = 5
  968. self.enter_frame['relief'] = "ridge"
  969. self.enter_frame.place(relx=0.2, rely=0.58, relwidth=0.6, relheight=0.17)
  970. height = 0.1
  971. for lb, text, enter, var, lb_w, text_w, enter_w, var_w in (
  972. zip(self.title, self.enter_title, self.enter, self.var,
  973. self.where_title, ["Where:", self.enter_title[1]], self.where_enter, self.where_var)):
  974. lb['font'] = title_font
  975. lb['text'] = text
  976. lb['bg'] = self.bg_color
  977. lb['anchor'] = 'e'
  978. lb_w['font'] = title_font
  979. lb_w['text'] = text_w
  980. lb_w['bg'] = self.bg_color_where
  981. lb_w['anchor'] = 'e'
  982. enter['font'] = title_font
  983. enter['textvariable'] = var
  984. enter_w['font'] = title_font
  985. enter_w['textvariable'] = var_w
  986. lb.place(relx=0.01, rely=height, relwidth=0.30, relheight=0.35)
  987. enter.place(relx=0.35, rely=height, relwidth=0.60, relheight=0.35)
  988. lb_w.place(relx=0.01, rely=height, relwidth=0.30, relheight=0.35)
  989. enter_w.place(relx=0.35, rely=height, relwidth=0.60, relheight=0.35)
  990. height += 0.43
  991. for btn, text, func in zip(self.btn,
  992. ["Update Advanced", "Update By UserID"],
  993. [self.update_by_where, self.update_by_uid]):
  994. btn['font'] = btn_font
  995. btn['text'] = text
  996. btn['bg'] = conf.tk_btn_bg
  997. btn['command'] = func
  998. self.btn[0].place(relx=0.55, rely=0.40, relwidth=0.25, relheight=0.08)
  999. self.btn[1].place(relx=0.55, rely=0.78, relwidth=0.25, relheight=0.08)
  1000. def update_by_uid(self):
  1001. ...
  1002. def update_by_where(self):
  1003. ...
  1004. def set_disable(self):
  1005. set_tk_disable_from_list(self.btn)
  1006. set_tk_disable_from_list(self.enter)
  1007. def reset_disable(self):
  1008. set_tk_disable_from_list(self.btn, flat='normal')
  1009. set_tk_disable_from_list(self.enter, flat='normal')
  1010. class UpdateUserScoreBase(UpdateUserProgramBase):
  1011. def __init__(self, station, win, color):
  1012. super(UpdateUserScoreBase, self).__init__(station, win, color, "UpdateScore")
  1013. self._conf(["UserID:", "Score:"], "#afdfe4")
  1014. def update_by_uid(self):
  1015. uid = self.enter[0].get()
  1016. score = int(self.enter[1].get())
  1017. event = tk_event.UpdateUserScoreEvent(self.station).start(score, f"UserID='{uid}'")
  1018. self.station.push_event(event)
  1019. def update_by_where(self):
  1020. where = self.where_enter[0].get()
  1021. score = int(self.where_enter[1].get())
  1022. event = tk_event.UpdateUserScoreEvent(self.station).start(score, where)
  1023. self.station.push_event(event)
  1024. class UpdateUserReputationBase(UpdateUserProgramBase):
  1025. def __init__(self, station, win, color):
  1026. super(UpdateUserReputationBase, self).__init__(station, win, color, "UpdateReputation")
  1027. self._conf(["UserID:", "Reputation:"], "#f8aba6")
  1028. def update_by_uid(self):
  1029. uid = self.enter[0].get()
  1030. reputation = int(self.enter[1].get())
  1031. event = tk_event.UpdateUserReputationEvent(self.station).start(reputation, f"UserID='{uid}'")
  1032. self.station.push_event(event)
  1033. def update_by_where(self):
  1034. where = self.where_enter[0].get()
  1035. reputation = int(self.where_enter[1].get())
  1036. event = tk_event.UpdateUserReputationEvent(self.station).start(reputation, where)
  1037. self.station.push_event(event)
  1038. class UpdateGarbageTypeProgram(AdminProgram):
  1039. def __init__(self, station, win, color):
  1040. super().__init__(station, win, color, "UpdateGarbageType")
  1041. self.enter_frame = tk.Frame(self.frame)
  1042. self.title: tk.Label = tk.Label(self.enter_frame)
  1043. self.enter: tk.Entry = tk.Entry(self.enter_frame)
  1044. self.type: List[tk.Radiobutton] = [tk.Radiobutton(self.frame) for _ in range(4)]
  1045. self.var: List[tk.Variable] = [tk.StringVar, tk.IntVar()]
  1046. self.where_frame = tk.Frame(self.frame)
  1047. self.where_title: tk.Label = tk.Label(self.where_frame)
  1048. self.where_enter: tk.Entry = tk.Entry(self.where_frame)
  1049. self.where_type: List[tk.Radiobutton] = [tk.Radiobutton(self.frame) for _ in range(4)]
  1050. self.where_var: List[tk.Variable] = [tk.StringVar, tk.IntVar()]
  1051. self.btn: List[tk.Button] = [tk.Button(self.frame), tk.Button(self.frame)]
  1052. self.__conf_font()
  1053. def __conf_font(self, n: int = 1):
  1054. self.title_font_size = int(16 * n)
  1055. self.btn_font_size = int(14 * n)
  1056. def conf_gui(self, n: int = 1):
  1057. self.__conf_font(n)
  1058. title_font = make_font(size=self.title_font_size)
  1059. btn_font = make_font(size=self.btn_font_size)
  1060. self.where_frame['bg'] = "#fdb933"
  1061. self.where_frame['bd'] = 5
  1062. self.where_frame['relief'] = "ridge"
  1063. self.where_frame.place(relx=0.2, rely=0.20, relwidth=0.6, relheight=0.10)
  1064. self.enter_frame['bg'] = "#fdb933"
  1065. self.enter_frame['bd'] = 5
  1066. self.enter_frame['relief'] = "ridge"
  1067. self.enter_frame.place(relx=0.2, rely=0.60, relwidth=0.6, relheight=0.10)
  1068. for lb, enter, radios, var, y, text in zip([self.title, self.where_title],
  1069. [self.enter, self.where_enter],
  1070. [self.type, self.where_type],
  1071. [self.var, self.where_var],
  1072. [0.32, 0.72],
  1073. ["GarbageID:", "Where:"]):
  1074. lb['font'] = title_font
  1075. lb['text'] = text
  1076. lb['bg'] = "#fdb933"
  1077. lb['anchor'] = 'e'
  1078. enter['font'] = title_font
  1079. enter['textvariable'] = var[0]
  1080. for i, radio in enumerate(radios):
  1081. radio['font'] = btn_font
  1082. radio['bg'] = self.color
  1083. radio['text'] = GarbageType.GarbageTypeStrList[i + 1]
  1084. radio['value'] = i + 1
  1085. radio['variable'] = var[1]
  1086. radio['anchor'] = 'w'
  1087. var[1].set(1)
  1088. radios[0].place(relx=0.20, rely=y + 0.00, relwidth=0.20, relheight=0.04)
  1089. radios[1].place(relx=0.60, rely=y + 0.00, relwidth=0.20, relheight=0.04)
  1090. radios[2].place(relx=0.20, rely=y + 0.05, relwidth=0.20, relheight=0.04)
  1091. radios[3].place(relx=0.60, rely=y + 0.05, relwidth=0.20, relheight=0.04)
  1092. lb.place(relx=0.02, rely=0.2, relwidth=0.25, relheight=0.48)
  1093. enter.place(relx=0.30, rely=0.2, relwidth=0.60, relheight=0.48)
  1094. for btn, text, func in zip(self.btn,
  1095. ["Update Advanced", "Update By GarbageID"],
  1096. [self.update_by_where, self.update_by_gid]):
  1097. btn['font'] = btn_font
  1098. btn['text'] = text
  1099. btn['bg'] = conf.tk_btn_bg
  1100. btn['command'] = func
  1101. self.btn[0].place(relx=0.55, rely=0.43, relwidth=0.25, relheight=0.08)
  1102. self.btn[1].place(relx=0.55, rely=0.83, relwidth=0.25, relheight=0.08)
  1103. def update_by_gid(self):
  1104. gid = self.enter.get()
  1105. type_ = self.var[1].get()
  1106. event = tk_event.UpdateGarbageTypeEvent(self.station).start(type_, f"GarbageID={gid}")
  1107. self.station.push_event(event)
  1108. def update_by_where(self):
  1109. where = self.where_enter.get()
  1110. type_ = self.where_var[1].get()
  1111. event = tk_event.UpdateGarbageTypeEvent(self.station).start(type_, where)
  1112. self.station.push_event(event)
  1113. def set_disable(self):
  1114. set_tk_disable_from_list(self.btn)
  1115. self.enter['state'] = 'disable'
  1116. self.where_enter['state'] = 'normal'
  1117. def reset_disable(self):
  1118. set_tk_disable_from_list(self.btn, flat='normal')
  1119. self.enter['state'] = 'normal'
  1120. self.where_enter['state'] = 'normal'
  1121. class UpdateGarbageCheckResultProgram(AdminProgram):
  1122. def __init__(self, station, win, color):
  1123. super().__init__(station, win, color, "UpdateGarbageCheckResult")
  1124. self.enter_frame = tk.Frame(self.frame)
  1125. self.title: tk.Label = tk.Label(self.enter_frame)
  1126. self.enter: tk.Entry = tk.Entry(self.enter_frame)
  1127. self.type: List[tk.Radiobutton] = [tk.Radiobutton(self.frame) for _ in range(2)]
  1128. self.var: List[tk.Variable] = [tk.StringVar, tk.IntVar()]
  1129. self.where_frame = tk.Frame(self.frame)
  1130. self.where_title: tk.Label = tk.Label(self.where_frame)
  1131. self.where_enter: tk.Entry = tk.Entry(self.where_frame)
  1132. self.where_type: List[tk.Radiobutton] = [tk.Radiobutton(self.frame) for _ in range(2)]
  1133. self.where_var: List[tk.Variable] = [tk.StringVar, tk.IntVar()]
  1134. self.btn: List[tk.Button] = [tk.Button(self.frame), tk.Button(self.frame)]
  1135. self.__conf_font()
  1136. def __conf_font(self, n: int = 1):
  1137. self.title_font_size = int(16 * n)
  1138. self.btn_font_size = int(14 * n)
  1139. def conf_gui(self, n: int = 1):
  1140. self.__conf_font(n)
  1141. title_font = make_font(size=self.title_font_size)
  1142. btn_font = make_font(size=self.btn_font_size)
  1143. self.where_frame['bg'] = "#abc88b"
  1144. self.where_frame['bd'] = 5
  1145. self.where_frame['relief'] = "ridge"
  1146. self.where_frame.place(relx=0.2, rely=0.20, relwidth=0.6, relheight=0.10)
  1147. self.enter_frame['bg'] = "#abc88b"
  1148. self.enter_frame['bd'] = 5
  1149. self.enter_frame['relief'] = "ridge"
  1150. self.enter_frame.place(relx=0.2, rely=0.60, relwidth=0.6, relheight=0.10)
  1151. for lb, enter, radios, var, y, text in zip([self.title, self.where_title],
  1152. [self.enter, self.where_enter],
  1153. [self.type, self.where_type],
  1154. [self.var, self.where_var],
  1155. [0.32, 0.72],
  1156. ["GarbageID:", "Where:"]):
  1157. lb['font'] = title_font
  1158. lb['text'] = text
  1159. lb['bg'] = "#abc88b"
  1160. lb['anchor'] = 'e'
  1161. enter['font'] = title_font
  1162. enter['textvariable'] = var[0]
  1163. for i, radio in enumerate(radios):
  1164. radio['font'] = btn_font
  1165. radio['bg'] = self.color
  1166. radio['text'] = ["Fail", "Pass"][i]
  1167. radio['value'] = i
  1168. radio['variable'] = var[1]
  1169. radio['anchor'] = 'w'
  1170. var[1].set(1)
  1171. radios[0].place(relx=0.20, rely=y + 0.00, relwidth=0.20, relheight=0.04)
  1172. radios[1].place(relx=0.60, rely=y + 0.00, relwidth=0.20, relheight=0.04)
  1173. lb.place(relx=0.02, rely=0.2, relwidth=0.25, relheight=0.48)
  1174. enter.place(relx=0.30, rely=0.2, relwidth=0.60, relheight=0.48)
  1175. for btn, text, func in zip(self.btn,
  1176. ["Update Advanced", "Update By GarbageID"],
  1177. [self.update_by_where, self.update_by_gid]):
  1178. btn['font'] = btn_font
  1179. btn['bg'] = conf.tk_btn_bg
  1180. btn['text'] = text
  1181. btn['command'] = func
  1182. self.btn[0].place(relx=0.55, rely=0.38, relwidth=0.25, relheight=0.08)
  1183. self.btn[1].place(relx=0.55, rely=0.78, relwidth=0.25, relheight=0.08)
  1184. def update_by_gid(self):
  1185. gid = self.enter.get()
  1186. check = (self.var[1].get() == 1)
  1187. event = tk_event.UpdateGarbageCheckEvent(self.station).start(check, f"GarbageID={gid}")
  1188. self.station.push_event(event)
  1189. def update_by_where(self):
  1190. where = self.where_enter.get()
  1191. check = (self.where_var[1].get() == 1)
  1192. event = tk_event.UpdateGarbageCheckEvent(self.station).start(check, where)
  1193. self.station.push_event(event)
  1194. def set_disable(self):
  1195. set_tk_disable_from_list(self.btn)
  1196. self.enter['state'] = 'disable'
  1197. self.where_enter['state'] = 'normal'
  1198. def reset_disable(self):
  1199. set_tk_disable_from_list(self.btn, flat='normal')
  1200. self.enter['state'] = 'normal'
  1201. self.where_enter['state'] = 'normal'
  1202. all_program = [WelcomeProgram, CreateNormalUserProgram, CreateManagerUserProgram, CreateAutoNormalUserProgram,
  1203. CreateGarbageProgram, DeleteUserProgram, DeleteUsersProgram, DeleteGarbageProgram,
  1204. DeleteGarbageMoreProgram, DeleteAllGarbageProgram, SearchUserProgram, SearchUserAdvancedProgram,
  1205. SearchGarbageProgram, SearchGarbageAdvancedProgram, SearchAdvancedProgram, UpdateUserScoreBase,
  1206. UpdateUserReputationBase, UpdateGarbageTypeProgram, UpdateGarbageCheckResultProgram,
  1207. ExportGarbageProgram, ExportUserProgram]