admin_program.py 67 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743
  1. import abc
  2. import tkinter as tk
  3. import tkinter.ttk as ttk
  4. from tkinter.filedialog import askdirectory, askopenfilename
  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. from conf import Config
  9. from . import admin
  10. from . 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, "欢迎页")
  35. self.title = tk.Label(self.frame)
  36. self.info = tk.Label(self.frame)
  37. self.__conf_font()
  38. def __conf_font(self, n: int = 1):
  39. self.title_font_size = int(25 * n)
  40. self.info_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. info_font = make_font(size=self.info_font_size)
  45. self.title['font'] = title_font
  46. self.title['bg'] = self.color
  47. self.title['text'] = '欢迎使用 HGSSystem 管理员系统\n[帮助]'
  48. self.info['bg'] = self.color
  49. self.info['font'] = info_font
  50. self.info['anchor'] = 'nw'
  51. self.info['justify'] = 'left'
  52. self.info['text'] = (f'''
  53. HGSSystem 管理者界面:
  54. 1) 点击菜单按钮进入子菜单或程序
  55. 2) 创建 菜单包含创建类的程序
  56. 3) 删除 菜单包含删除类的程序
  57. 4) 搜索 菜单包含数据分析类的程序
  58. 5) 更新 菜单包含数据更新类的程序
  59. 6) 当离开操作系统时请退出登录以确保安全
  60. 7) 只能使用具有管理员权限的账号登陆系统
  61. 8) 只有admin用户可以完成危险操作(例如删除所有垃圾袋数据)
  62. 程序的运行:
  63. 1) 在菜单中选中程序后,根据程序界面提示完成操作
  64. 2) 操作过程通常会显示进度条,除非任务执行迅速
  65. 3) 结果通常会被反馈, 且不会自动消失
  66. 系统登录:
  67. 1) 仅Manager用户可以登录
  68. 关于彩蛋: 存在
  69. '''.strip())
  70. self.title.place(relx=0.1, rely=0.0, relwidth=0.8, relheight=0.2)
  71. self.info.place(relx=0.05, rely=0.21, relwidth=0.90, relheight=0.75)
  72. def set_disable(self):
  73. pass
  74. def reset_disable(self):
  75. pass
  76. class AboutProgram(AdminProgram):
  77. def __init__(self, station, win, color):
  78. super().__init__(station, win, color, "关于")
  79. self.title = tk.Label(self.frame)
  80. self.info = tk.Label(self.frame)
  81. self.__conf_font()
  82. def __conf_font(self, n: int = 1):
  83. self.title_font_size = int(25 * n)
  84. self.info_font_size = int(14 * n)
  85. def conf_gui(self, n: int = 1):
  86. self.__conf_font(n)
  87. title_font = make_font(size=self.title_font_size, weight="bold")
  88. info_font = make_font(size=self.info_font_size)
  89. self.title['font'] = title_font
  90. self.title['bg'] = self.color
  91. self.title['text'] = '关于 HGSSystem 管理员系统'
  92. self.info['bg'] = self.color
  93. self.info['font'] = info_font
  94. self.info['anchor'] = 'nw'
  95. self.info['justify'] = 'left'
  96. self.info['text'] = Config.about_info
  97. self.title.place(relx=0.1, rely=0.0, relwidth=0.8, relheight=0.2)
  98. self.info.place(relx=0.05, rely=0.21, relwidth=0.90, relheight=0.75)
  99. def set_disable(self):
  100. pass
  101. def reset_disable(self):
  102. pass
  103. class CreateUserProgramBase(AdminProgram):
  104. def __init__(self, station, win, color, title: str):
  105. super().__init__(station, win, color, title)
  106. self.enter_frame = tk.Frame(self.frame)
  107. self.title: List[tk.Label] = [tk.Label(self.enter_frame) for _ in range(3)]
  108. self.enter: List[tk.Entry] = [tk.Entry(self.enter_frame) for _ in range(3)]
  109. self.var: List[tk.Variable] = [tk.StringVar() for _ in range(3)]
  110. self.btn: List[tk.Button] = [tk.Button(self.frame) for _ in range(2)]
  111. self._conf("#FA8072", False) # 默认颜色
  112. self.__conf_font()
  113. def _conf(self, bg_color, is_manager: bool):
  114. self.bg_color = bg_color
  115. self.is_manager = is_manager
  116. return self
  117. def __conf_font(self, n: int = 1):
  118. self.title_font_size = int(16 * n)
  119. self.btn_font_size = int(14 * n)
  120. def conf_gui(self, n: int = 1):
  121. self.__conf_font(n)
  122. title_font = make_font(size=self.title_font_size)
  123. btn_font = make_font(size=self.btn_font_size)
  124. self.enter_frame['bg'] = self.bg_color
  125. self.enter_frame['bd'] = 5
  126. self.enter_frame['relief'] = "ridge"
  127. self.enter_frame.place(relx=0.2, rely=0.3, relwidth=0.6, relheight=0.30)
  128. height = 0.1
  129. for lb, text, enter, var in zip(self.title, ["用户名:", "用户密码:", "手机号:"], self.enter, self.var):
  130. lb['font'] = title_font
  131. lb['text'] = text
  132. lb['bg'] = self.bg_color
  133. lb['anchor'] = 'e'
  134. enter['font'] = title_font
  135. enter['textvariable'] = var
  136. lb.place(relx=0.01, rely=height, relwidth=0.30, relheight=0.17)
  137. enter.place(relx=0.35, rely=height, relwidth=0.60, relheight=0.17)
  138. height += 0.30
  139. for btn, text, x, func in zip(self.btn,
  140. ["创建用户", "获取用户ID"],
  141. [0.2, 0.6],
  142. [lambda: self.create_by_name(), lambda: self.get_uid()]):
  143. btn['font'] = btn_font
  144. btn['text'] = text
  145. btn['bg'] = Config.tk_btn_bg
  146. btn['command'] = func
  147. btn.place(relx=x, rely=0.7, relwidth=0.2, relheight=0.08)
  148. def __get_info(self) -> Optional[Tuple[uname_t, passwd_t, str]]:
  149. name: uname_t = self.var[0].get()
  150. passwd: passwd_t = self.var[1].get()
  151. phone: str = self.var[2].get()
  152. if len(name) == 0 or len(passwd) == 0 or len(phone) != 11:
  153. self.station.show_msg("用户创建失败", "请再次尝试, 输入用户名, 用户密码和11位手机号")
  154. return None
  155. return name, passwd, phone
  156. def create_by_name(self):
  157. res = self.__get_info()
  158. if res is None:
  159. return
  160. name, passwd, phone = res
  161. event = tk_event.CreateUserEvent(self.station).start(name, passwd, phone, self.is_manager)
  162. self.station.push_event(event)
  163. def get_uid(self):
  164. res = self.__get_info()
  165. if res is None:
  166. return
  167. name, passwd, phone = res
  168. uid = create_uid(name, passwd, phone)
  169. self.station.show_msg("获取用户ID", f"用户名: {name}\n用户ID: {uid}")
  170. def set_disable(self):
  171. set_tk_disable_from_list(self.btn)
  172. set_tk_disable_from_list(self.enter)
  173. def reset_disable(self):
  174. set_tk_disable_from_list(self.btn, flat='normal')
  175. set_tk_disable_from_list(self.enter, flat='normal')
  176. class CreateNormalUserProgram(CreateUserProgramBase):
  177. def __init__(self, station, win, color):
  178. super(CreateNormalUserProgram, self).__init__(station, win, color, "创建普通用户")
  179. class CreateManagerUserProgram(CreateUserProgramBase):
  180. def __init__(self, station, win, color):
  181. super(CreateManagerUserProgram, self).__init__(station, win, color, "创建管理员")
  182. self._conf("#4b5cc4", True)
  183. class CreateAutoNormalUserProgram(AdminProgram):
  184. def __init__(self, station, win, color):
  185. super().__init__(station, win, color, "创建自动用户")
  186. self.enter_frame = tk.Frame(self.frame)
  187. self.title: tk.Label = tk.Label(self.enter_frame)
  188. self.enter: tk.Entry = tk.Entry(self.enter_frame)
  189. self.var: tk.Variable = tk.StringVar()
  190. self.btn: tk.Button = tk.Button(self.frame) # create(生成用户) try(计算uid)
  191. self.__conf_font()
  192. def __conf_font(self, n: int = 1):
  193. self.title_font_size = int(16 * n)
  194. self.btn_font_size = int(14 * n)
  195. def conf_gui(self, n: int = 1):
  196. self.__conf_font(n)
  197. title_font = make_font(size=self.title_font_size)
  198. btn_font = make_font(size=self.btn_font_size)
  199. self.enter_frame['bg'] = "#bce672"
  200. self.enter_frame['bd'] = 5
  201. self.enter_frame['relief'] = "ridge"
  202. self.enter_frame.place(relx=0.2, rely=0.3, relwidth=0.6, relheight=0.12)
  203. self.title['font'] = title_font
  204. self.title['text'] = "手机号:"
  205. self.title['bg'] = "#bce672"
  206. self.title['anchor'] = 'e'
  207. self.enter['font'] = title_font
  208. self.enter['textvariable'] = self.var
  209. self.title.place(relx=0.02, rely=0.25, relwidth=0.25, relheight=0.50)
  210. self.enter.place(relx=0.30, rely=0.25, relwidth=0.60, relheight=0.50)
  211. self.btn['font'] = btn_font
  212. self.btn['text'] = "创建用户"
  213. self.btn['bg'] = Config.tk_btn_bg
  214. self.btn['command'] = lambda: self.create_user()
  215. self.btn.place(relx=0.4, rely=0.7, relwidth=0.2, relheight=0.08)
  216. def create_user(self):
  217. phone = self.var.get()
  218. if len(phone) != 11:
  219. self.station.show_msg("UserInfoError", "Please, enter Phone(11)")
  220. event = tk_event.CreateUserEvent(self.station).start(None, None, phone, False)
  221. self.station.push_event(event)
  222. def set_disable(self):
  223. self.btn['state'] = 'disable'
  224. self.enter['state'] = 'disable'
  225. def reset_disable(self):
  226. self.btn['state'] = 'normal'
  227. self.enter['state'] = 'normal'
  228. class CreateGarbageProgram(AdminProgram):
  229. def __init__(self, station, win, color):
  230. super().__init__(station, win, color, "创建垃圾袋")
  231. self.enter_frame = tk.Frame(self.frame)
  232. self.title: List[tk.Label] = [tk.Label(self.enter_frame), tk.Label(self.enter_frame)]
  233. self.enter: List[tk.Entry] = [tk.Entry(self.enter_frame), tk.Entry(self.enter_frame)]
  234. self.var: List[tk.Variable] = [tk.StringVar(), tk.StringVar()]
  235. self.create_btn: tk.Button = tk.Button(self.frame)
  236. self.file_btn: tk.Button = tk.Button(self.frame)
  237. self.__conf_font()
  238. def __conf_font(self, n: int = 1):
  239. self.title_font_size = int(16 * n)
  240. self.btn_font_size = int(14 * n)
  241. def conf_gui(self, n: int = 1):
  242. self.__conf_font(n)
  243. title_font = make_font(size=self.title_font_size)
  244. btn_font = make_font(size=self.btn_font_size)
  245. self.enter_frame['bg'] = "#b69968"
  246. self.enter_frame['bd'] = 5
  247. self.enter_frame['relief'] = "ridge"
  248. self.enter_frame.place(relx=0.2, rely=0.3, relwidth=0.6, relheight=0.17)
  249. height = 0.1
  250. for lb, text, enter, var in zip(self.title, ["数量:", "导出位置:"], self.enter, self.var):
  251. lb['font'] = title_font
  252. lb['text'] = text
  253. lb['bg'] = "#b69968"
  254. lb['anchor'] = 'e'
  255. enter['font'] = title_font
  256. enter['textvariable'] = var
  257. lb.place(relx=0.01, rely=height, relwidth=0.30, relheight=0.35)
  258. enter.place(relx=0.35, rely=height, relwidth=0.60, relheight=0.35)
  259. height += 0.43
  260. for btn, text, x, func in zip([self.create_btn, self.file_btn],
  261. ["创建垃圾袋", "选择目录"],
  262. [0.2, 0.6],
  263. [lambda: self.create_garbage(), lambda: self.choose_file()]):
  264. btn['font'] = btn_font
  265. btn['text'] = text
  266. btn['bg'] = Config.tk_btn_bg
  267. btn['command'] = func
  268. btn.place(relx=x, rely=0.7, relwidth=0.2, relheight=0.08)
  269. def choose_file(self):
  270. path = askdirectory(title='选择二维码导出位置')
  271. self.var[1].set(path)
  272. def create_garbage(self):
  273. try:
  274. count = int(self.var[0].get())
  275. if count <= 0:
  276. raise ValueError
  277. except (ValueError, TypeError):
  278. self.station.show_msg("类型错误", "数量必须为大于0的数字")
  279. else:
  280. path = self.var[1].get()
  281. if len(path) == 0:
  282. path = None
  283. event = tk_event.CreateGarbageEvent(self.station).start(path, count)
  284. self.station.push_event(event)
  285. def set_disable(self):
  286. self.create_btn['state'] = 'disable'
  287. self.file_btn['state'] = 'disable'
  288. set_tk_disable_from_list(self.enter)
  289. def reset_disable(self):
  290. self.create_btn['state'] = 'normal'
  291. self.file_btn['state'] = 'normal'
  292. set_tk_disable_from_list(self.enter, flat='normal')
  293. class ExportProgramBase(AdminProgram):
  294. def __init__(self, station, win, color, title: str):
  295. super().__init__(station, win, color, title)
  296. self.gid_frame = tk.Frame(self.frame)
  297. self.gid_title: List[tk.Label] = [tk.Label(self.gid_frame), tk.Label(self.gid_frame)]
  298. self.gid_enter: List[tk.Entry] = [tk.Entry(self.gid_frame), tk.Entry(self.gid_frame)]
  299. self.gid_var: List[tk.Variable] = [tk.StringVar(), tk.StringVar()]
  300. self.where_frame = tk.Frame(self.frame)
  301. self.where_title: List[tk.Label] = [tk.Label(self.where_frame), tk.Label(self.where_frame)]
  302. self.where_enter: List[tk.Entry] = [tk.Entry(self.where_frame), tk.Entry(self.where_frame)]
  303. self.where_var: List[tk.Variable] = [tk.StringVar(), tk.StringVar()]
  304. self.create_btn: List[tk.Button] = [tk.Button(self.frame), tk.Button(self.frame)]
  305. self.file_btn: List[tk.Button] = [tk.Button(self.frame), tk.Button(self.frame)]
  306. self._conf("", [], [], [])
  307. self.__conf_font()
  308. def _conf(self, bg_color: str, title_id, title_where, title_command):
  309. self.bg_color = bg_color
  310. self.title_id = title_id
  311. self.title_where = title_where
  312. self.title_command = title_command
  313. def __conf_font(self, n: int = 1):
  314. self.title_font_size = int(16 * n)
  315. self.btn_font_size = int(14 * n)
  316. def conf_gui(self, n: int = 1):
  317. self.__conf_font(n)
  318. title_font = make_font(size=self.title_font_size)
  319. btn_font = make_font(size=self.btn_font_size)
  320. self.where_frame['bg'] = self.bg_color
  321. self.where_frame['bd'] = 5
  322. self.where_frame['relief'] = "ridge"
  323. self.where_frame.place(relx=0.2, rely=0.2, relwidth=0.6, relheight=0.17)
  324. self.gid_frame['bg'] = self.bg_color
  325. self.gid_frame['bd'] = 5
  326. self.gid_frame['relief'] = "ridge"
  327. self.gid_frame.place(relx=0.2, rely=0.6, relwidth=0.6, relheight=0.17)
  328. height = 0.1
  329. for lb, text, enter, var, lb_w, text_w, enter_w, var_w in zip(
  330. self.gid_title, self.title_id, self.gid_enter, self.gid_var,
  331. self.where_title, self.title_where, self.where_enter, self.where_var):
  332. lb['font'] = title_font
  333. lb['text'] = text
  334. lb['bg'] = self.bg_color
  335. lb['anchor'] = 'e'
  336. lb_w['font'] = title_font
  337. lb_w['text'] = text_w
  338. lb_w['bg'] = self.bg_color
  339. lb_w['anchor'] = 'e'
  340. enter['textvariable'] = var
  341. enter['font'] = title_font
  342. enter_w['textvariable'] = var_w
  343. enter_w['font'] = title_font
  344. lb.place(relx=0.01, rely=height, relwidth=0.30, relheight=0.35)
  345. enter.place(relx=0.35, rely=height, relwidth=0.60, relheight=0.35)
  346. lb_w.place(relx=0.01, rely=height, relwidth=0.30, relheight=0.35)
  347. enter_w.place(relx=0.35, rely=height, relwidth=0.60, relheight=0.35)
  348. height += 0.43
  349. for btn, text in zip(self.create_btn + self.file_btn, self.title_command):
  350. btn['font'] = btn_font
  351. btn['text'] = text
  352. btn['bg'] = Config.tk_btn_bg
  353. self.create_btn[1]['command'] = self.export_where
  354. self.create_btn[0]['command'] = self.export_id
  355. self.create_btn[1].place(relx=0.2, rely=0.39, relwidth=0.25, relheight=0.08)
  356. self.create_btn[0].place(relx=0.2, rely=0.79, relwidth=0.25, relheight=0.08)
  357. self.file_btn[1]['command'] = self.choose_file_where
  358. self.file_btn[0]['command'] = self.choose_file_id
  359. self.file_btn[1].place(relx=0.6, rely=0.39, relwidth=0.2, relheight=0.08)
  360. self.file_btn[0].place(relx=0.6, rely=0.79, relwidth=0.2, relheight=0.08)
  361. def choose_file_id(self):
  362. path = askdirectory(title='选择二维码导出位置')
  363. self.gid_var[1].set(path)
  364. def choose_file_where(self):
  365. path = askdirectory(title='选择二维码导出位置')
  366. self.where_var[1].set(path)
  367. def export_id(self):
  368. ...
  369. def export_where(self):
  370. ...
  371. def set_disable(self):
  372. set_tk_disable_from_list(self.gid_enter)
  373. set_tk_disable_from_list(self.create_btn)
  374. set_tk_disable_from_list(self.file_btn)
  375. def reset_disable(self):
  376. set_tk_disable_from_list(self.gid_enter, flat='normal')
  377. set_tk_disable_from_list(self.create_btn, flat='normal')
  378. set_tk_disable_from_list(self.file_btn, flat='normal')
  379. class ExportGarbageProgram(ExportProgramBase):
  380. def __init__(self, station, win, color):
  381. super().__init__(station, win, color, "导出垃圾袋二维码")
  382. self._conf("#afdfe4", ["垃圾袋ID:", "导出位置:"], ["条件:", "导出位置:"],
  383. ["根据垃圾袋ID导出", "根据条件导出", "选择目录", "选择目录"])
  384. def export_id(self):
  385. gid = self.gid_var[0].get()
  386. path = self.gid_var[1].get()
  387. event = tk_event.ExportGarbageByIDEvent(self.station).start(path, gid)
  388. self.station.push_event(event)
  389. def export_where(self):
  390. where = self.where_var[0].get()
  391. path = self.where_var[1].get()
  392. event = tk_event.ExportGarbageAdvancedEvent(self.station).start(path, where)
  393. self.station.push_event(event)
  394. class ExportUserProgram(ExportProgramBase):
  395. def __init__(self, station, win, color):
  396. super().__init__(station, win, color, "导出用户二维码")
  397. self._conf("#f69c9f", ["用户ID:", "导出位置:"], ["条件:", "导出位置:"],
  398. ["根据用户ID导出", "根据条件导出", "选择目录", "选择目录"])
  399. def export_id(self):
  400. uid = self.gid_var[0].get()
  401. path = self.gid_var[1].get()
  402. event = tk_event.ExportUserByIDEvent(self.station).start(path, uid)
  403. self.station.push_event(event)
  404. def export_where(self):
  405. where = self.where_var[0].get()
  406. path = self.where_var[1].get()
  407. event = tk_event.ExportUserAdvancedEvent(self.station).start(path, where)
  408. self.station.push_event(event)
  409. class CreateUserFromCSVProgram(AdminProgram):
  410. def __init__(self, station, win, color):
  411. super().__init__(station, win, color, "从CSV导入用户")
  412. self.auto_frame = tk.Frame(self.frame)
  413. self.auto_title: tk.Label = tk.Label(self.auto_frame)
  414. self.auto_enter: tk.Entry = tk.Entry(self.auto_frame)
  415. self.auto_var: tk.Variable = tk.StringVar()
  416. self.enter_frame = tk.Frame(self.frame)
  417. self.path_title: tk.Label = tk.Label(self.enter_frame)
  418. self.path_enter: tk.Entry = tk.Entry(self.enter_frame)
  419. self.path_var: tk.Variable = tk.StringVar()
  420. self.create_btn: List[tk.Button] = [tk.Button(self.frame), tk.Button(self.frame)]
  421. self.file_btn: List[tk.Button] = [tk.Button(self.frame), tk.Button(self.frame)]
  422. self.__conf_font()
  423. def __conf_font(self, n: int = 1):
  424. self.title_font_size = int(16 * n)
  425. self.btn_font_size = int(14 * n)
  426. def conf_gui(self, n: int = 1):
  427. self.__conf_font(n)
  428. title_font = make_font(size=self.title_font_size)
  429. btn_font = make_font(size=self.btn_font_size)
  430. self.enter_frame['bg'] = "#EEE8AA"
  431. self.enter_frame['bd'] = 5
  432. self.enter_frame['relief'] = "ridge"
  433. self.enter_frame.place(relx=0.2, rely=0.2, relwidth=0.6, relheight=0.12)
  434. self.auto_frame['bg'] = "#EEE8AA"
  435. self.auto_frame['bd'] = 5
  436. self.auto_frame['relief'] = "ridge"
  437. self.auto_frame.place(relx=0.2, rely=0.6, relwidth=0.6, relheight=0.12)
  438. self.auto_title['font'] = title_font
  439. self.auto_title['text'] = "CSV文件:"
  440. self.auto_title['bg'] = "#EEE8AA"
  441. self.auto_title['anchor'] = 'e'
  442. self.path_title['font'] = title_font
  443. self.path_title['text'] = "CSV文件:"
  444. self.path_title['bg'] = "#EEE8AA"
  445. self.path_title['anchor'] = 'e'
  446. self.auto_enter['textvariable'] = self.auto_var
  447. self.auto_enter['font'] = title_font
  448. self.path_enter['textvariable'] = self.path_var
  449. self.path_enter['font'] = title_font
  450. self.auto_title.place(relx=0.01, rely=0.25, relwidth=0.30, relheight=0.50)
  451. self.auto_enter.place(relx=0.35, rely=0.25, relwidth=0.60, relheight=0.50)
  452. self.path_title.place(relx=0.01, rely=0.25, relwidth=0.30, relheight=0.50)
  453. self.path_enter.place(relx=0.35, rely=0.25, relwidth=0.60, relheight=0.50)
  454. for btn, text in zip(self.create_btn + self.file_btn,
  455. ["创建用户", "创建自动用户", "选择CSV", "选择CSV"]):
  456. btn['font'] = btn_font
  457. btn['text'] = text
  458. btn['bg'] = Config.tk_btn_bg
  459. self.create_btn[0]['command'] = self.create
  460. self.create_btn[1]['command'] = self.create_auto
  461. self.create_btn[0].place(relx=0.2, rely=0.34, relwidth=0.25, relheight=0.08)
  462. self.create_btn[1].place(relx=0.2, rely=0.74, relwidth=0.25, relheight=0.08)
  463. self.file_btn[0]['command'] = self.choose_file
  464. self.file_btn[1]['command'] = self.choose_file_auto
  465. self.file_btn[0].place(relx=0.6, rely=0.34, relwidth=0.2, relheight=0.08)
  466. self.file_btn[1].place(relx=0.6, rely=0.74, relwidth=0.2, relheight=0.08)
  467. def choose_file_auto(self):
  468. path = askopenfilename(title='选择CSV文件', filetypes=[("CSV", ".csv")])
  469. self.auto_var.set(path)
  470. def choose_file(self):
  471. path = askopenfilename(title='选择CSV文件', filetypes=[("CSV", ".csv")])
  472. self.path_var.set(path)
  473. def create_auto(self):
  474. path = self.auto_var.get()
  475. event = tk_event.CreateAutoUserFromCSVEvent(self.station).start(path)
  476. self.station.push_event(event)
  477. def create(self):
  478. path = self.path_var.get()
  479. event = tk_event.CreateUserFromCSVEvent(self.station).start(path)
  480. self.station.push_event(event)
  481. def set_disable(self):
  482. self.auto_enter['state'] = 'disable'
  483. self.path_enter['state'] = 'disable'
  484. set_tk_disable_from_list(self.create_btn)
  485. set_tk_disable_from_list(self.file_btn)
  486. def reset_disable(self):
  487. self.auto_enter['state'] = 'normal'
  488. self.path_enter['state'] = 'normal'
  489. set_tk_disable_from_list(self.create_btn, flat='normal')
  490. set_tk_disable_from_list(self.file_btn, flat='normal')
  491. class DeleteUserProgram(AdminProgram):
  492. def __init__(self, station, win, color):
  493. super().__init__(station, win, color, "删除用户")
  494. self.uid_frame = tk.Frame(self.frame)
  495. self.uid_title: tk.Label = tk.Label(self.uid_frame)
  496. self.uid_enter: tk.Entry = tk.Entry(self.uid_frame)
  497. self.uid_var: tk.Variable = tk.StringVar()
  498. self.name_frame = tk.Frame(self.frame)
  499. self.name_title: List[tk.Label] = [tk.Label(self.name_frame) for _ in range(2)]
  500. self.name_enter: List[tk.Entry] = [tk.Entry(self.name_frame) for _ in range(2)]
  501. self.name_var: List[tk.Variable] = [tk.StringVar() for _ in range(2)]
  502. self.btn: List[tk.Button] = [tk.Button(self.frame) for _ in range(2)] # uid-del, name-passwd-del
  503. self.__conf_font()
  504. def __conf_font(self, n: int = 1):
  505. self.title_font_size = int(16 * n)
  506. self.btn_font_size = int(14 * n)
  507. def conf_gui(self, n: int = 1):
  508. self.__conf_font(n)
  509. title_font = make_font(size=self.title_font_size)
  510. btn_font = make_font(size=self.btn_font_size)
  511. self.uid_frame['bg'] = "#FA8072"
  512. self.uid_frame['bd'] = 5
  513. self.uid_frame['relief'] = "ridge"
  514. self.uid_frame.place(relx=0.2, rely=0.20, relwidth=0.6, relheight=0.10)
  515. self.name_frame['bg'] = "#FA8072"
  516. self.name_frame['bd'] = 5
  517. self.name_frame['relief'] = "ridge"
  518. self.name_frame.place(relx=0.2, rely=0.48, relwidth=0.6, relheight=0.25)
  519. height = 0.17
  520. for lb, text, enter, var in zip(self.name_title, ["用户名:", "密码:"], self.name_enter, self.name_var):
  521. lb['font'] = title_font
  522. lb['text'] = text
  523. lb['bg'] = "#FA8072"
  524. lb['anchor'] = 'e'
  525. enter['font'] = title_font
  526. enter['textvariable'] = var
  527. lb.place(relx=0.01, rely=height, relwidth=0.30, relheight=0.20)
  528. enter.place(relx=0.35, rely=height, relwidth=0.60, relheight=0.20)
  529. height += 0.45
  530. self.uid_title['font'] = title_font
  531. self.uid_title['text'] = "用户ID:"
  532. self.uid_title['bg'] = "#FA8072"
  533. self.uid_title['anchor'] = 'e'
  534. self.uid_enter['font'] = title_font
  535. self.uid_enter['textvariable'] = self.uid_var
  536. self.uid_title.place(relx=0.01, rely=0.25, relwidth=0.30, relheight=0.50)
  537. self.uid_enter.place(relx=0.35, rely=0.25, relwidth=0.60, relheight=0.50)
  538. for btn, text, func in zip(self.btn,
  539. ["通过用户ID删除", "通过用户名删除"],
  540. [lambda: self.del_by_uid(), lambda: self.del_by_name()]):
  541. btn['font'] = btn_font
  542. btn['text'] = text
  543. btn['bg'] = Config.tk_btn_bg
  544. btn['command'] = func
  545. self.btn[0].place(relx=0.6, rely=0.32, relwidth=0.2, relheight=0.08)
  546. self.btn[1].place(relx=0.6, rely=0.75, relwidth=0.2, relheight=0.08)
  547. def del_by_uid(self):
  548. uid = self.uid_var.get()
  549. if len(uid) != 32:
  550. self.station.show_warning("用户ID错误", "用户ID必须为32位")
  551. return
  552. event = tk_event.DelUserEvent(self.station).start(uid)
  553. self.station.push_event(event)
  554. def del_by_name(self):
  555. name = self.name_var[0].get()
  556. passwd = self.name_var[1].get()
  557. if len(name) == 0 or len(passwd) == 0:
  558. self.station.show_warning("用户名或密码错误", "请输入用户名和密码")
  559. return
  560. uid = create_uid(name, passwd)
  561. event = tk_event.DelUserEvent(self.station).start(uid)
  562. self.station.push_event(event)
  563. def set_disable(self):
  564. set_tk_disable_from_list(self.btn)
  565. set_tk_disable_from_list(self.name_enter)
  566. self.uid_enter['state'] = 'disable'
  567. def reset_disable(self):
  568. set_tk_disable_from_list(self.btn, flat='normal')
  569. set_tk_disable_from_list(self.name_enter, flat='normal')
  570. self.uid_enter['state'] = 'normal'
  571. class DeleteUsersProgram(AdminProgram):
  572. def __init__(self, station, win, color):
  573. super().__init__(station, win, color, "删除多个用户")
  574. self.enter_frame = tk.Frame(self.frame)
  575. self.title: tk.Label = tk.Label(self.enter_frame)
  576. self.enter: tk.Entry = tk.Entry(self.enter_frame)
  577. self.var: tk.Variable = tk.StringVar()
  578. self.btn: List[tk.Button] = [tk.Button(self.frame) for _ in range(2)] # del, scan
  579. self.__conf_font()
  580. def __conf_font(self, n: int = 1):
  581. self.title_font_size = int(16 * n)
  582. self.btn_font_size = int(14 * n)
  583. def conf_gui(self, n: int = 1):
  584. self.__conf_font(n)
  585. title_font = make_font(size=self.title_font_size)
  586. btn_font = make_font(size=self.btn_font_size)
  587. self.enter_frame['bg'] = "#48c0a3"
  588. self.enter_frame['bd'] = 5
  589. self.enter_frame['relief'] = "ridge"
  590. self.enter_frame.place(relx=0.2, rely=0.30, relwidth=0.6, relheight=0.10)
  591. self.title['font'] = title_font
  592. self.title['text'] = "条件:"
  593. self.title['anchor'] = 'e'
  594. self.title['bg'] = "#48c0a3"
  595. self.enter['font'] = title_font
  596. self.enter['textvariable'] = self.var
  597. self.title.place(relx=0.01, rely=0.25, relwidth=0.30, relheight=0.50)
  598. self.enter.place(relx=0.35, rely=0.25, relwidth=0.60, relheight=0.50)
  599. for btn, text, x, func in zip(self.btn,
  600. ["删除", "扫描"],
  601. [0.2, 0.6],
  602. [lambda: self.delete_user(), lambda: self.scan_user()]):
  603. btn['font'] = btn_font
  604. btn['text'] = text
  605. btn['bg'] = Config.tk_btn_bg
  606. btn['command'] = func
  607. btn.place(relx=x, rely=0.6, relwidth=0.2, relheight=0.08)
  608. def delete_user(self):
  609. where = self.var.get()
  610. if len(where) == 0:
  611. self.station.show_warning("条件错误", "条件必须为正确的SQL语句")
  612. return
  613. event = tk_event.DelUserFromWhereEvent(self.station).start(where)
  614. self.station.push_event(event)
  615. def scan_user(self):
  616. where = self.var.get()
  617. if len(where) == 0:
  618. self.station.show_warning("条件错误", "条件必须为正确的SQL语句")
  619. return
  620. event = tk_event.DelUserFromWhereScanEvent(self.station).start(where)
  621. self.station.push_event(event)
  622. def set_disable(self):
  623. set_tk_disable_from_list(self.btn)
  624. self.enter['state'] = 'disable'
  625. def reset_disable(self):
  626. set_tk_disable_from_list(self.btn, flat='normal')
  627. self.enter['state'] = 'normal'
  628. class DeleteGarbageProgramBase(AdminProgram):
  629. def __init__(self, station, win, color, title: str):
  630. super().__init__(station, win, color, title)
  631. self.enter_frame = tk.Frame(self.frame)
  632. self.title: tk.Label = tk.Label(self.enter_frame)
  633. self.enter: tk.Entry = tk.Entry(self.enter_frame)
  634. self.var: tk.Variable = tk.StringVar()
  635. self.int_var: tk.Variable = tk.IntVar()
  636. self.int_var.set(0)
  637. self.radio: List[tk.Radiobutton] = [tk.Radiobutton(self.frame) for _ in range(4)]
  638. self.btn: tk.Button = tk.Button(self.frame)
  639. self.__conf_font()
  640. self._conf()
  641. def _conf(self, title: str = "垃圾袋ID:", color: str = "#b69968", support_del_all: bool = True):
  642. self.frame_title = title
  643. self.frame_color = color
  644. self.support_del_all = support_del_all
  645. def __conf_font(self, n: int = 1):
  646. self.title_font_size = int(16 * n)
  647. self.btn_font_size = int(14 * n)
  648. def conf_gui(self, n: int = 1):
  649. self.__conf_font(n)
  650. title_font = make_font(size=self.title_font_size)
  651. btn_font = make_font(size=self.btn_font_size)
  652. self.enter_frame['bg'] = self.frame_color
  653. self.enter_frame['bd'] = 5
  654. self.enter_frame['relief'] = "ridge"
  655. self.enter_frame.place(relx=0.2, rely=0.30, relwidth=0.6, relheight=0.10)
  656. self.title['font'] = title_font
  657. self.title['text'] = self.frame_title
  658. self.title['bg'] = self.frame_color
  659. self.title['anchor'] = 'e'
  660. self.enter['font'] = title_font
  661. self.enter['textvariable'] = self.var
  662. self.title.place(relx=0.01, rely=0.25, relwidth=0.30, relheight=0.50)
  663. self.enter.place(relx=0.35, rely=0.25, relwidth=0.60, relheight=0.50)
  664. for i in range(4):
  665. radio = self.radio[i]
  666. radio['font'] = btn_font
  667. radio['text'] = ['均可', '仅未使用', '仅待检测', '仅已检测'][i]
  668. radio['bg'] = self.color
  669. radio['value'] = i
  670. radio['variable'] = self.int_var
  671. radio['anchor'] = 'w'
  672. if not self.support_del_all:
  673. self.int_var.set(1)
  674. self.radio[0]['state'] = 'disable'
  675. self.radio[0].place(relx=0.20, rely=0.43, relwidth=0.20, relheight=0.1)
  676. self.radio[1].place(relx=0.60, rely=0.43, relwidth=0.20, relheight=0.1)
  677. self.radio[2].place(relx=0.20, rely=0.55, relwidth=0.20, relheight=0.1)
  678. self.radio[3].place(relx=0.60, rely=0.55, relwidth=0.20, relheight=0.1)
  679. self.btn['font'] = btn_font
  680. self.btn['text'] = '删除'
  681. self.btn['bg'] = Config.tk_btn_bg
  682. self.btn['command'] = lambda: self.delete_garbage()
  683. self.btn.place(relx=0.4, rely=0.68, relwidth=0.2, relheight=0.08)
  684. def delete_garbage(self):
  685. ...
  686. def set_disable(self):
  687. self.enter['state'] = 'disable'
  688. self.btn['state'] = 'disable'
  689. def reset_disable(self):
  690. self.enter['state'] = 'normal'
  691. self.btn['state'] = 'normal'
  692. class DeleteGarbageProgram(DeleteGarbageProgramBase):
  693. def __init__(self, station, win, color):
  694. super(DeleteGarbageProgram, self).__init__(station, win, color, "删除垃圾袋")
  695. def delete_garbage(self):
  696. where = self.int_var.get()
  697. assert where in [0, 1, 2, 3]
  698. gid = self.var.get()
  699. if len(gid) == 0:
  700. self.station.show_warning("垃圾袋ID错误", "请输入正确的垃圾袋ID")
  701. return
  702. event = tk_event.DelGarbageEvent(self.station).start(gid, where)
  703. self.station.push_event(event)
  704. class DeleteGarbageMoreProgram(DeleteGarbageProgramBase):
  705. def __init__(self, station, win, color):
  706. super(DeleteGarbageMoreProgram, self).__init__(station, win, color, "删除多个垃圾袋")
  707. self.scan_btn = tk.Button(self.frame)
  708. self._conf("条件:", "#f58f98", False)
  709. def conf_gui(self, n: int = 1):
  710. super(DeleteGarbageMoreProgram, self).conf_gui(n)
  711. self.btn.place_forget()
  712. self.btn.place(relx=0.2, rely=0.68, relwidth=0.2, relheight=0.08)
  713. self.scan_btn['font'] = make_font(size=self.btn_font_size)
  714. self.scan_btn['text'] = '扫描'
  715. self.scan_btn['bg'] = Config.tk_btn_bg
  716. self.scan_btn['command'] = self.scan_garbage
  717. self.scan_btn.place(relx=0.6, rely=0.68, relwidth=0.2, relheight=0.08)
  718. def set_disable(self):
  719. super(DeleteGarbageMoreProgram, self).set_disable()
  720. self.scan_btn['state'] = 'disable'
  721. def reset_disable(self):
  722. super(DeleteGarbageMoreProgram, self).reset_disable()
  723. self.scan_btn['state'] = 'normal'
  724. def delete_garbage(self):
  725. where = self.int_var.get()
  726. assert where in [1, 2, 3]
  727. where_sql = self.var.get()
  728. if len(where_sql) == 0:
  729. self.station.show_warning("条件错误", "条件必须为正确的SQL语句")
  730. return
  731. event = tk_event.DelGarbageWhereEvent(self.station).start(where, where_sql)
  732. self.station.push_event(event)
  733. def scan_garbage(self):
  734. where = self.int_var.get()
  735. assert where in [1, 2, 3]
  736. where_sql = self.var.get()
  737. if len(where_sql) == 0:
  738. self.station.show_warning("条件错误", "条件必须为正确的SQL语句")
  739. return
  740. event = tk_event.DelGarbageWhereScanEvent(self.station).start(where, where_sql)
  741. self.station.push_event(event)
  742. class DeleteAllGarbageProgram(AdminProgram):
  743. def __init__(self, station, win, color):
  744. super().__init__(station, win, color, "删除所有垃圾袋")
  745. self.dangerous: tk.Label = tk.Label(self.frame)
  746. self.enter_frame = tk.Frame(self.frame)
  747. self.title: tk.Label = tk.Label(self.enter_frame)
  748. self.enter: tk.Entry = tk.Entry(self.enter_frame)
  749. self.var: tk.Variable = tk.StringVar()
  750. self.btn: List[tk.Button] = [tk.Button(self.frame) for _ in range(2)] # del, scan
  751. self.__conf_font()
  752. def __conf_font(self, n: int = 1):
  753. self.danger_font_size = int(20 * n)
  754. self.title_font_size = int(16 * n)
  755. self.btn_font_size = int(14 * n)
  756. def conf_gui(self, n: int = 1):
  757. self.__conf_font(n)
  758. danger_font = make_font(size=self.danger_font_size, weight="bold", underline=1)
  759. title_font = make_font(size=self.title_font_size)
  760. btn_font = make_font(size=self.btn_font_size)
  761. danger_btn_font = make_font(size=self.btn_font_size, weight="bold", overstrike=1)
  762. self.dangerous['bg'] = self.color
  763. self.dangerous['font'] = danger_font
  764. self.dangerous['fg'] = "#f20c00"
  765. self.dangerous['text'] = ("确定要从数据库删除所有垃圾袋吗?\n"
  766. "请输入[admin]用户的密码再继续操作.\n"
  767. "只有[admin]用户具有该操作的权限.\n"
  768. "这是相当危险的操作.\n"
  769. "操作后数据库可能无法恢复原数据.\n"
  770. "SuperHuan和程序的缔造者不会对\n"
  771. "此操作负责.\n"
  772. "删库跑路可不是一件好事.\n"
  773. "请遵守当地法律法规.")
  774. self.dangerous.place(relx=0.05, rely=0.03, relwidth=0.9, relheight=0.53)
  775. self.enter_frame['bg'] = "#f20c00"
  776. self.enter_frame['bd'] = 5
  777. self.enter_frame['relief'] = "ridge"
  778. self.enter_frame.place(relx=0.2, rely=0.60, relwidth=0.6, relheight=0.10)
  779. self.title['font'] = title_font
  780. self.title['text'] = "密码:"
  781. self.title['bg'] = "#f20c00"
  782. self.title['anchor'] = 'e'
  783. self.enter['font'] = title_font
  784. self.enter['textvariable'] = self.var
  785. self.title.place(relx=0.01, rely=0.25, relwidth=0.30, relheight=0.50)
  786. self.enter.place(relx=0.35, rely=0.25, relwidth=0.60, relheight=0.50)
  787. for btn, text, x in zip(self.btn, ["删除", "扫描"], [0.2, 0.6]):
  788. btn['text'] = text
  789. btn.place(relx=x, rely=0.78, relwidth=0.2, relheight=0.08)
  790. self.btn[0]['font'] = danger_btn_font
  791. self.btn[0]['bg'] = "#f20c00"
  792. self.btn[0]['command'] = lambda: self.delete_garbage()
  793. self.btn[1]['font'] = btn_font
  794. self.btn[1]['bg'] = Config.tk_btn_bg
  795. self.btn[1]['command'] = lambda: self.scan_garbage()
  796. def scan_garbage(self):
  797. event = tk_event.DelAllGarbageScanEvent(self.station) # 不需要start
  798. self.station.push_event(event)
  799. def delete_garbage(self):
  800. passwd = self.var.get()
  801. if len(passwd) == 0:
  802. self.station.show_warning("密码错误", "请输入正确的[admin]用户密码")
  803. user = find_user_by_name('admin', passwd, self.station.get_db())
  804. if user is None or not user.is_manager():
  805. self.station.show_warning("密码错误", "请输入正确的[admin]用户密码")
  806. return
  807. event = tk_event.DelAllGarbageEvent(self.station) # 不需要start
  808. self.station.push_event(event)
  809. def set_disable(self):
  810. set_tk_disable_from_list(self.btn)
  811. self.enter['state'] = 'disable'
  812. def reset_disable(self):
  813. set_tk_disable_from_list(self.btn, flat='normal')
  814. self.enter['state'] = 'normal'
  815. class SearchProgramBase(AdminProgram, metaclass=abc.ABCMeta):
  816. def __init__(self, station, win, color, title: str):
  817. super().__init__(station, win, color, title)
  818. self.view_frame = tk.Frame(self.frame)
  819. self.view = ttk.Treeview(self.view_frame)
  820. self.y_scroll = tk.Scrollbar(self.view_frame)
  821. self.x_scroll = tk.Scrollbar(self.view_frame)
  822. def conf_view_gui(self, columns: list, relx, rely, relwidth, relheight,
  823. x_scroll=0.05, y_scroll=0.02, color: str = "#FA8072"):
  824. self.view_frame['bg'] = color
  825. self.view_frame['bd'] = 2
  826. self.view_frame['relief'] = "ridge"
  827. self.view_frame.place(relx=relx, rely=rely, relwidth=relwidth, relheight=relheight)
  828. self.view['columns'] = columns
  829. self.view['show'] = 'headings'
  830. self.view['selectmode'] = 'none'
  831. for i in columns:
  832. self.view.column(i, anchor="c")
  833. self.view.heading(i, text=i)
  834. self.y_scroll['orient'] = 'vertical'
  835. self.y_scroll['command'] = self.view.yview
  836. self.view['yscrollcommand'] = self.y_scroll.set
  837. self.x_scroll['orient'] = 'horizontal'
  838. self.x_scroll['command'] = self.view.xview
  839. self.view['xscrollcommand'] = self.x_scroll.set
  840. self.view.place(relx=0.0, rely=0.0, relwidth=1 - y_scroll, relheight=1 - x_scroll)
  841. self.y_scroll.place(relx=0.98, rely=0.0, relwidth=y_scroll, relheight=1.0)
  842. self.x_scroll.place(relx=0.0, rely=1 - x_scroll, relwidth=1 - y_scroll, relheight=x_scroll)
  843. class SearchUserProgram(SearchProgramBase):
  844. def __init__(self, station, win, color):
  845. super().__init__(station, win, color, "搜索用户")
  846. self.enter_frame = tk.Frame(self.frame)
  847. self.title: List[tk.Label] = [tk.Label(self.enter_frame) for _ in range(3)]
  848. self.enter: List[tk.Entry] = [tk.Entry(self.enter_frame) for _ in range(3)]
  849. self.var: List[tk.Variable] = [tk.StringVar() for _ in range(3)]
  850. self.check: List[Tuple[tk.Checkbutton, tk.Variable]] = [(tk.Checkbutton(self.enter_frame), tk.IntVar())
  851. for _ in range(3)]
  852. self.btn: tk.Button = tk.Button(self.frame)
  853. self._columns = ["UserID", "Name", "Phone", "Score", "Reputation", "IsManager"]
  854. self._columns_ch = ["用户ID[UserID]", "用户名[Name]", "手机号[Phone]",
  855. "积分[Score]", "垃圾分类信用[Reputation]", "是否管理员[IsManager]"]
  856. self.__conf_font()
  857. def __conf_font(self, n: int = 1):
  858. self.title_font_size = int(16 * n)
  859. self.btn_font_size = int(14 * n)
  860. def conf_gui(self, n: int = 1):
  861. self.__conf_font(n)
  862. title_font = make_font(size=self.title_font_size)
  863. btn_font = make_font(size=self.btn_font_size)
  864. self.enter_frame['bg'] = "#FA8072"
  865. self.enter_frame['bd'] = 5
  866. self.enter_frame['relief'] = "ridge"
  867. self.enter_frame.place(relx=0.2, rely=0.0, relwidth=0.6, relheight=0.30)
  868. height = 0.1
  869. for lb, text, enter, var, check in zip(self.title,
  870. ["用户ID:", "用户名:", "手机号:"],
  871. self.enter, self.var, self.check):
  872. lb['font'] = title_font
  873. lb['text'] = text
  874. lb['bg'] = "#FA8072"
  875. lb['anchor'] = 'e'
  876. enter['font'] = title_font
  877. enter['textvariable'] = var
  878. check[0]['font'] = title_font
  879. check[0]['text'] = ''
  880. check[0]['bg'] = "#FA8072"
  881. check[0]['variable'] = check[1]
  882. check[1].set(1)
  883. lb.place(relx=0.01, rely=height, relwidth=0.30, relheight=0.17)
  884. enter.place(relx=0.35, rely=height, relwidth=0.55, relheight=0.17)
  885. check[0].place(relx=0.92, rely=height, relwidth=0.04, relheight=0.17)
  886. height += 0.30
  887. self.btn['font'] = btn_font
  888. self.btn['text'] = "搜索"
  889. self.btn['bg'] = Config.tk_btn_bg
  890. self.btn['command'] = self.search_user
  891. self.btn.place(relx=0.4, rely=0.9, relwidth=0.2, relheight=0.08)
  892. self.conf_view_gui(self._columns_ch, relx=0.05, rely=0.32, relwidth=0.9, relheight=0.55)
  893. def search_user(self):
  894. use_uid = self.check[0][1].get()
  895. use_name = self.check[1][1].get()
  896. use_phone = self.check[2][1].get()
  897. uid = None
  898. name = None
  899. phone = None
  900. if use_uid:
  901. uid = self.var[0].get()
  902. if len(uid) == 0:
  903. uid = None
  904. if use_name:
  905. name = self.var[1].get()
  906. if len(name) == 0:
  907. name = None
  908. if use_phone:
  909. phone = self.var[2].get()
  910. if len(phone) == 0:
  911. phone = None
  912. event = tk_event.SearchUserEvent(self.station).start(self._columns, uid, name, phone, self)
  913. self.station.push_event(event)
  914. def set_disable(self):
  915. self.btn['state'] = 'disable'
  916. set_tk_disable_from_list(self.enter)
  917. def reset_disable(self):
  918. self.btn['state'] = 'normal'
  919. set_tk_disable_from_list(self.enter, flat='normal')
  920. class SearchAdvancedProgramBase(SearchProgramBase, metaclass=abc.ABCMeta):
  921. def __init__(self, station, win, color, title: str):
  922. super().__init__(station, win, color, title)
  923. self.enter_frame = tk.Frame(self.frame)
  924. self.title: tk.Label = tk.Label(self.enter_frame)
  925. self.enter: tk.Entry = tk.Entry(self.enter_frame)
  926. self.var: tk.Variable = tk.StringVar()
  927. self.btn: tk.Button = tk.Button(self.frame)
  928. self._conf([], [], "#FA8072") # 默认颜色
  929. self.__conf_font()
  930. def _conf(self, columns: list, columns_ch: list, bg_color):
  931. self.bg_color = bg_color
  932. self._columns = columns
  933. self._columns_ch = columns_ch
  934. return self
  935. def __conf_font(self, n: int = 1):
  936. self.title_font_size = int(16 * n)
  937. self.btn_font_size = int(14 * n)
  938. def conf_gui(self, n: int = 1):
  939. self.__conf_font(n)
  940. title_font = make_font(size=self.title_font_size)
  941. btn_font = make_font(size=self.btn_font_size)
  942. self.enter_frame['bg'] = self.bg_color
  943. self.enter_frame['bd'] = 5
  944. self.enter_frame['relief'] = "ridge"
  945. self.enter_frame.place(relx=0.2, rely=0.00, relwidth=0.6, relheight=0.10)
  946. self.title['font'] = title_font
  947. self.title['bg'] = self.bg_color
  948. self.title['text'] = "条件:"
  949. self.title['anchor'] = 'e'
  950. self.enter['font'] = title_font
  951. self.enter['textvariable'] = self.var
  952. self.title.place(relx=0.01, rely=0.25, relwidth=0.30, relheight=0.50)
  953. self.enter.place(relx=0.35, rely=0.25, relwidth=0.60, relheight=0.50)
  954. self.btn['text'] = "搜索"
  955. self.btn['font'] = btn_font
  956. self.btn['bg'] = Config.tk_btn_bg
  957. self.btn['command'] = self.search
  958. self.btn.place(relx=0.4, rely=0.9, relwidth=0.2, relheight=0.08)
  959. self.conf_view_gui(self._columns_ch, relx=0.05, rely=0.12, relwidth=0.9, relheight=0.76)
  960. def search(self):
  961. ...
  962. def set_disable(self):
  963. self.btn['state'] = 'disable'
  964. self.enter['state'] = 'disable'
  965. def reset_disable(self):
  966. self.btn['state'] = 'normal'
  967. self.enter['state'] = 'normal'
  968. class SearchUserAdvancedProgram(SearchAdvancedProgramBase):
  969. def __init__(self, station, win, color):
  970. super(SearchUserAdvancedProgram, self).__init__(station, win, color, "高级搜索-用户")
  971. columns = ["UserID", "Name", "Phone", "Score", "Reputation", "IsManager"]
  972. columns_ch = ["用户ID[UserID]", "用户名[Name]", "手机号[Phone]",
  973. "积分[Score]", "垃圾分类信用[Reputation]", "是否管理员[IsManager]"]
  974. self._conf(columns, columns_ch, '#48c0a3')
  975. def search(self):
  976. where = self.var.get()
  977. event = tk_event.SearchUserAdvancedEvent(self.station).start(self._columns, where, self)
  978. self.station.push_event(event)
  979. class SearchGarbageProgram(SearchProgramBase):
  980. def __init__(self, station, win, color):
  981. super().__init__(station, win, color, "搜索垃圾袋")
  982. self.enter_frame = tk.Frame(self.frame)
  983. self.title: List[tk.Label] = [tk.Label(self.enter_frame) for _ in range(8)]
  984. self.enter: List[tk.Entry] = [tk.Entry(self.enter_frame) for _ in range(8)]
  985. self.var: List[tk.Variable] = [tk.StringVar() for _ in range(8)]
  986. self.check: List[Tuple[tk.Checkbutton, tk.Variable]] = [(tk.Checkbutton(self.enter_frame), tk.IntVar())
  987. for _ in range(8)]
  988. self._columns = ["GarbageID", "UserID", "CheckerID", "CreateTime", "UseTime", "Location", "GarbageType",
  989. "CheckResult"]
  990. self._columns_zh = ["垃圾袋ID[GarbageID]", "使用者ID[UserID]", "检测者ID[CheckerID]", "创建时间[CreateTime]",
  991. "使用时间[UseTime]", "使用地点[Location]", "垃圾类型[GarbageType]", "检测结果[CheckResult]"]
  992. self.btn: tk.Button = tk.Button(self.frame)
  993. self.__conf_font()
  994. def __conf_font(self, n: int = 1):
  995. self.title_font_size = int(16 * n)
  996. self.btn_font_size = int(14 * n)
  997. def conf_gui(self, n: int = 1):
  998. self.__conf_font(n)
  999. title_font = make_font(size=self.title_font_size)
  1000. btn_font = make_font(size=self.btn_font_size)
  1001. self.enter_frame['bg'] = "#7bbfea"
  1002. self.enter_frame['bd'] = 5
  1003. self.enter_frame['relief'] = "ridge"
  1004. self.enter_frame.place(relx=0.2, rely=0.0, relwidth=0.6, relheight=0.47)
  1005. height = 0.02
  1006. for lb, text, enter, var, check in zip(self.title,
  1007. ["垃圾袋ID:", "使用者ID:", "检查者ID:", "创建时间:", "使用时间:",
  1008. "使用地点:", "垃圾类型:", "检测结果:"],
  1009. self.enter, self.var, self.check):
  1010. lb['font'] = title_font
  1011. lb['text'] = text
  1012. lb['bg'] = "#7bbfea"
  1013. lb['anchor'] = 'e'
  1014. enter['font'] = title_font
  1015. enter['textvariable'] = var
  1016. check[0]['font'] = title_font
  1017. check[0]['bg'] = "#7bbfea"
  1018. check[0]['text'] = ''
  1019. check[0]['variable'] = check[1]
  1020. check[1].set(1)
  1021. lb.place(relx=0.01, rely=height, relwidth=0.30, relheight=0.10)
  1022. enter.place(relx=0.35, rely=height, relwidth=0.55, relheight=0.10)
  1023. check[0].place(relx=0.92, rely=height, relwidth=0.04, relheight=0.10)
  1024. height += 0.121
  1025. self.btn['font'] = btn_font
  1026. self.btn['bg'] = Config.tk_btn_bg
  1027. self.btn['text'] = "Search"
  1028. self.btn['command'] = self.search_user
  1029. self.btn.place(relx=0.4, rely=0.9, relwidth=0.2, relheight=0.08)
  1030. self.conf_view_gui(self._columns_zh, relx=0.05, rely=0.49, relwidth=0.9, relheight=0.38, x_scroll=0.07)
  1031. def search_user(self):
  1032. keys = ["gid", "uid", "cuid", "create_time", "use_time", "loc", "type_", "check"]
  1033. key_values = {}
  1034. for i, key in enumerate(keys):
  1035. ck = self.check[i][1].get()
  1036. if ck:
  1037. res = self.enter[i].get()
  1038. if len(res) > 0:
  1039. key_values[key] = res
  1040. continue
  1041. key_values[key] = None
  1042. event = tk_event.SearchGarbageEvent(self.station).start(self._columns, key_values, self)
  1043. self.station.push_event(event)
  1044. def set_disable(self):
  1045. self.btn['state'] = 'disable'
  1046. set_tk_disable_from_list(self.enter)
  1047. def reset_disable(self):
  1048. self.btn['state'] = 'normal'
  1049. set_tk_disable_from_list(self.enter, flat='normal')
  1050. class SearchGarbageAdvancedProgram(SearchAdvancedProgramBase):
  1051. def __init__(self, station, win, color):
  1052. super(SearchGarbageAdvancedProgram, self).__init__(station, win, color, "高级搜索-垃圾袋")
  1053. columns = ["GarbageID", "UserID", "CheckerID", "CreateTime", "UseTime", "Location", "GarbageType",
  1054. "CheckResult"]
  1055. columns_zh = ["垃圾袋ID[GarbageID]", "使用者ID[UserID]", "检测者ID[CheckerID]", "创建时间[CreateTime]",
  1056. "使用时间[UseTime]", "使用地点[Location]", "垃圾类型[GarbageType]", "检测结果[CheckResult]"]
  1057. self._conf(columns, columns_zh, '#d1923f')
  1058. def search(self):
  1059. where = self.var.get()
  1060. event = tk_event.SearchGarbageAdvancedEvent(self.station).start(self._columns, where, self)
  1061. self.station.push_event(event)
  1062. class SearchAdvancedProgram(SearchAdvancedProgramBase):
  1063. def __init__(self, station, win, color):
  1064. super(SearchAdvancedProgram, self).__init__(station, win, color, "高级搜索")
  1065. columns = ["GarbageID", "UserID", "UserName", "UserPhone", "UserScore",
  1066. "UserReputation", "CheckerID", "CheckerName", "CheckerPhone",
  1067. "CreateTime", "UseTime", "Location", "GarbageType", "CheckResult"]
  1068. columns_zh = ["垃圾袋ID[GarbageID]", "使用者ID[UserID]", "使用者名[UserName]", "使用者手机号[UserPhone]",
  1069. "使用者积分[UserScore]", "使用者垃圾分类信用[UserReputation]", "检测者ID[CheckerID]",
  1070. "检测这名[CheckerName]", "检测者手机号[CheckerPhone]", "创建时间[CreateTime]", "使用时间[UseTime]",
  1071. "使用地点[Location]", "垃圾类型[GarbageType]", "检测结果[CheckResult]"]
  1072. self._conf(columns, columns_zh, '#426ab3')
  1073. def search(self):
  1074. where = self.var.get()
  1075. event = tk_event.SearchAdvancedEvent(self.station).start(self._columns, where, self)
  1076. self.station.push_event(event)
  1077. class UpdateUserProgramBase(AdminProgram):
  1078. def __init__(self, station, win, color, title: str):
  1079. super().__init__(station, win, color, title)
  1080. self.enter_frame = tk.Frame(self.frame)
  1081. self.title: List[tk.Label] = [tk.Label(self.enter_frame) for _ in range(2)]
  1082. self.enter: List[tk.Entry] = [tk.Entry(self.enter_frame) for _ in range(2)]
  1083. self.var: List[tk.Variable] = [tk.StringVar() for _ in range(2)]
  1084. self.where_frame = tk.Frame(self.frame)
  1085. self.where_title: List[tk.Label] = [tk.Label(self.where_frame) for _ in range(2)]
  1086. self.where_enter: List[tk.Entry] = [tk.Entry(self.where_frame) for _ in range(2)]
  1087. self.where_var: List[tk.Variable] = [tk.StringVar() for _ in range(2)]
  1088. self.btn: List[tk.Button] = [tk.Button(self.frame), tk.Button(self.frame)]
  1089. self._conf(["", ""], "#FA8072")
  1090. self.__conf_font()
  1091. def _conf(self, title: List[str], bg_color: str):
  1092. self.bg_color = bg_color
  1093. self.bg_color_where = bg_color
  1094. self.enter_title = title
  1095. def __conf_font(self, n: int = 1):
  1096. self.title_font_size = int(16 * n)
  1097. self.btn_font_size = int(14 * n)
  1098. def conf_gui(self, n: int = 1):
  1099. self.__conf_font(n)
  1100. title_font = make_font(size=self.title_font_size)
  1101. btn_font = make_font(size=self.btn_font_size)
  1102. self.where_frame['bg'] = self.bg_color_where
  1103. self.where_frame['bd'] = 5
  1104. self.where_frame['relief'] = "ridge"
  1105. self.where_frame.place(relx=0.2, rely=0.20, relwidth=0.6, relheight=0.17)
  1106. self.enter_frame['bg'] = self.bg_color
  1107. self.enter_frame['bd'] = 5
  1108. self.enter_frame['relief'] = "ridge"
  1109. self.enter_frame.place(relx=0.2, rely=0.58, relwidth=0.6, relheight=0.17)
  1110. height = 0.1
  1111. for lb, text, enter, var, lb_w, text_w, enter_w, var_w in (
  1112. zip(self.title, self.enter_title, self.enter, self.var,
  1113. self.where_title, ["条件:", self.enter_title[1]], self.where_enter, self.where_var)):
  1114. lb['font'] = title_font
  1115. lb['text'] = text
  1116. lb['bg'] = self.bg_color
  1117. lb['anchor'] = 'e'
  1118. lb_w['font'] = title_font
  1119. lb_w['text'] = text_w
  1120. lb_w['bg'] = self.bg_color_where
  1121. lb_w['anchor'] = 'e'
  1122. enter['font'] = title_font
  1123. enter['textvariable'] = var
  1124. enter_w['font'] = title_font
  1125. enter_w['textvariable'] = var_w
  1126. lb.place(relx=0.01, rely=height, relwidth=0.30, relheight=0.35)
  1127. enter.place(relx=0.35, rely=height, relwidth=0.60, relheight=0.35)
  1128. lb_w.place(relx=0.01, rely=height, relwidth=0.30, relheight=0.35)
  1129. enter_w.place(relx=0.35, rely=height, relwidth=0.60, relheight=0.35)
  1130. height += 0.43
  1131. for btn, text, func in zip(self.btn,
  1132. ["通过条件更新", "通过用户ID更新"],
  1133. [self.update_by_where, self.update_by_uid]):
  1134. btn['font'] = btn_font
  1135. btn['text'] = text
  1136. btn['bg'] = Config.tk_btn_bg
  1137. btn['command'] = func
  1138. self.btn[0].place(relx=0.55, rely=0.40, relwidth=0.25, relheight=0.08)
  1139. self.btn[1].place(relx=0.55, rely=0.78, relwidth=0.25, relheight=0.08)
  1140. def update_by_uid(self):
  1141. ...
  1142. def update_by_where(self):
  1143. ...
  1144. def set_disable(self):
  1145. set_tk_disable_from_list(self.btn)
  1146. set_tk_disable_from_list(self.enter)
  1147. def reset_disable(self):
  1148. set_tk_disable_from_list(self.btn, flat='normal')
  1149. set_tk_disable_from_list(self.enter, flat='normal')
  1150. class UpdateUserScoreBase(UpdateUserProgramBase):
  1151. def __init__(self, station, win, color):
  1152. super(UpdateUserScoreBase, self).__init__(station, win, color, "更新用户-积分")
  1153. self._conf(["用户ID:", "积分:"], "#afdfe4")
  1154. def update_by_uid(self):
  1155. uid = self.enter[0].get()
  1156. score = int(self.enter[1].get())
  1157. event = tk_event.UpdateUserScoreEvent(self.station).start(score, f"UserID='{uid}'")
  1158. self.station.push_event(event)
  1159. def update_by_where(self):
  1160. where = self.where_enter[0].get()
  1161. score = int(self.where_enter[1].get())
  1162. event = tk_event.UpdateUserScoreEvent(self.station).start(score, where)
  1163. self.station.push_event(event)
  1164. class UpdateUserReputationBase(UpdateUserProgramBase):
  1165. def __init__(self, station, win, color):
  1166. super(UpdateUserReputationBase, self).__init__(station, win, color, "更新用户-垃圾分类信用")
  1167. self._conf(["用户ID:", "垃圾分类信用:"], "#f8aba6")
  1168. def update_by_uid(self):
  1169. uid = self.enter[0].get()
  1170. reputation = int(self.enter[1].get())
  1171. event = tk_event.UpdateUserReputationEvent(self.station).start(reputation, f"UserID='{uid}'")
  1172. self.station.push_event(event)
  1173. def update_by_where(self):
  1174. where = self.where_enter[0].get()
  1175. reputation = int(self.where_enter[1].get())
  1176. event = tk_event.UpdateUserReputationEvent(self.station).start(reputation, where)
  1177. self.station.push_event(event)
  1178. class UpdateGarbageTypeProgram(AdminProgram):
  1179. def __init__(self, station, win, color):
  1180. super().__init__(station, win, color, "更新垃圾袋-垃圾类型")
  1181. self.enter_frame = tk.Frame(self.frame)
  1182. self.title: tk.Label = tk.Label(self.enter_frame)
  1183. self.enter: tk.Entry = tk.Entry(self.enter_frame)
  1184. self.type: List[tk.Radiobutton] = [tk.Radiobutton(self.frame) for _ in range(4)]
  1185. self.var: List[tk.Variable] = [tk.StringVar, tk.IntVar()]
  1186. self.where_frame = tk.Frame(self.frame)
  1187. self.where_title: tk.Label = tk.Label(self.where_frame)
  1188. self.where_enter: tk.Entry = tk.Entry(self.where_frame)
  1189. self.where_type: List[tk.Radiobutton] = [tk.Radiobutton(self.frame) for _ in range(4)]
  1190. self.where_var: List[tk.Variable] = [tk.StringVar, tk.IntVar()]
  1191. self.btn: List[tk.Button] = [tk.Button(self.frame), tk.Button(self.frame)]
  1192. self.__conf_font()
  1193. def __conf_font(self, n: int = 1):
  1194. self.title_font_size = int(16 * n)
  1195. self.btn_font_size = int(14 * n)
  1196. def conf_gui(self, n: int = 1):
  1197. self.__conf_font(n)
  1198. title_font = make_font(size=self.title_font_size)
  1199. btn_font = make_font(size=self.btn_font_size)
  1200. self.where_frame['bg'] = "#fdb933"
  1201. self.where_frame['bd'] = 5
  1202. self.where_frame['relief'] = "ridge"
  1203. self.where_frame.place(relx=0.2, rely=0.20, relwidth=0.6, relheight=0.10)
  1204. self.enter_frame['bg'] = "#fdb933"
  1205. self.enter_frame['bd'] = 5
  1206. self.enter_frame['relief'] = "ridge"
  1207. self.enter_frame.place(relx=0.2, rely=0.60, relwidth=0.6, relheight=0.10)
  1208. for lb, enter, radios, var, y, text in zip([self.title, self.where_title],
  1209. [self.enter, self.where_enter],
  1210. [self.type, self.where_type],
  1211. [self.var, self.where_var],
  1212. [0.32, 0.72],
  1213. ["垃圾袋ID:", "条件:"]):
  1214. lb['font'] = title_font
  1215. lb['text'] = text
  1216. lb['bg'] = "#fdb933"
  1217. lb['anchor'] = 'e'
  1218. enter['font'] = title_font
  1219. enter['textvariable'] = var[0]
  1220. for i, radio in enumerate(radios):
  1221. radio['font'] = btn_font
  1222. radio['bg'] = self.color
  1223. radio['text'] = GarbageType.GarbageTypeStrList_ch[i + 1]
  1224. radio['value'] = i + 1
  1225. radio['variable'] = var[1]
  1226. radio['anchor'] = 'w'
  1227. var[1].set(1)
  1228. radios[0].place(relx=0.20, rely=y + 0.00, relwidth=0.20, relheight=0.04)
  1229. radios[1].place(relx=0.60, rely=y + 0.00, relwidth=0.20, relheight=0.04)
  1230. radios[2].place(relx=0.20, rely=y + 0.05, relwidth=0.20, relheight=0.04)
  1231. radios[3].place(relx=0.60, rely=y + 0.05, relwidth=0.20, relheight=0.04)
  1232. lb.place(relx=0.02, rely=0.2, relwidth=0.25, relheight=0.48)
  1233. enter.place(relx=0.30, rely=0.2, relwidth=0.60, relheight=0.48)
  1234. for btn, text, func in zip(self.btn,
  1235. ["通过条件更新", "通过垃圾袋ID更新"],
  1236. [self.update_by_where, self.update_by_gid]):
  1237. btn['font'] = btn_font
  1238. btn['text'] = text
  1239. btn['bg'] = Config.tk_btn_bg
  1240. btn['command'] = func
  1241. self.btn[0].place(relx=0.55, rely=0.43, relwidth=0.25, relheight=0.08)
  1242. self.btn[1].place(relx=0.55, rely=0.83, relwidth=0.25, relheight=0.08)
  1243. def update_by_gid(self):
  1244. gid = self.enter.get()
  1245. type_ = self.var[1].get()
  1246. event = tk_event.UpdateGarbageTypeEvent(self.station).start(type_, f"GarbageID={gid}")
  1247. self.station.push_event(event)
  1248. def update_by_where(self):
  1249. where = self.where_enter.get()
  1250. type_ = self.where_var[1].get()
  1251. event = tk_event.UpdateGarbageTypeEvent(self.station).start(type_, where)
  1252. self.station.push_event(event)
  1253. def set_disable(self):
  1254. set_tk_disable_from_list(self.btn)
  1255. self.enter['state'] = 'disable'
  1256. self.where_enter['state'] = 'normal'
  1257. def reset_disable(self):
  1258. set_tk_disable_from_list(self.btn, flat='normal')
  1259. self.enter['state'] = 'normal'
  1260. self.where_enter['state'] = 'normal'
  1261. class UpdateGarbageCheckResultProgram(AdminProgram):
  1262. def __init__(self, station, win, color):
  1263. super().__init__(station, win, color, "更新垃圾袋-检测结果")
  1264. self.enter_frame = tk.Frame(self.frame)
  1265. self.title: tk.Label = tk.Label(self.enter_frame)
  1266. self.enter: tk.Entry = tk.Entry(self.enter_frame)
  1267. self.type: List[tk.Radiobutton] = [tk.Radiobutton(self.frame) for _ in range(2)]
  1268. self.var: List[tk.Variable] = [tk.StringVar, tk.IntVar()]
  1269. self.where_frame = tk.Frame(self.frame)
  1270. self.where_title: tk.Label = tk.Label(self.where_frame)
  1271. self.where_enter: tk.Entry = tk.Entry(self.where_frame)
  1272. self.where_type: List[tk.Radiobutton] = [tk.Radiobutton(self.frame) for _ in range(2)]
  1273. self.where_var: List[tk.Variable] = [tk.StringVar, tk.IntVar()]
  1274. self.btn: List[tk.Button] = [tk.Button(self.frame), tk.Button(self.frame)]
  1275. self.__conf_font()
  1276. def __conf_font(self, n: int = 1):
  1277. self.title_font_size = int(16 * n)
  1278. self.btn_font_size = int(14 * n)
  1279. def conf_gui(self, n: int = 1):
  1280. self.__conf_font(n)
  1281. title_font = make_font(size=self.title_font_size)
  1282. btn_font = make_font(size=self.btn_font_size)
  1283. self.where_frame['bg'] = "#abc88b"
  1284. self.where_frame['bd'] = 5
  1285. self.where_frame['relief'] = "ridge"
  1286. self.where_frame.place(relx=0.2, rely=0.20, relwidth=0.6, relheight=0.10)
  1287. self.enter_frame['bg'] = "#abc88b"
  1288. self.enter_frame['bd'] = 5
  1289. self.enter_frame['relief'] = "ridge"
  1290. self.enter_frame.place(relx=0.2, rely=0.60, relwidth=0.6, relheight=0.10)
  1291. for lb, enter, radios, var, y, text in zip([self.title, self.where_title],
  1292. [self.enter, self.where_enter],
  1293. [self.type, self.where_type],
  1294. [self.var, self.where_var],
  1295. [0.32, 0.72],
  1296. ["垃圾袋ID:", "条件:"]):
  1297. lb['font'] = title_font
  1298. lb['text'] = text
  1299. lb['bg'] = "#abc88b"
  1300. lb['anchor'] = 'e'
  1301. enter['font'] = title_font
  1302. enter['textvariable'] = var[0]
  1303. for i, radio in enumerate(radios):
  1304. radio['font'] = btn_font
  1305. radio['bg'] = self.color
  1306. radio['text'] = ["投放错误", "投放正确"][i]
  1307. radio['value'] = i
  1308. radio['variable'] = var[1]
  1309. radio['anchor'] = 'w'
  1310. var[1].set(1)
  1311. radios[0].place(relx=0.20, rely=y + 0.00, relwidth=0.20, relheight=0.04)
  1312. radios[1].place(relx=0.60, rely=y + 0.00, relwidth=0.20, relheight=0.04)
  1313. lb.place(relx=0.02, rely=0.2, relwidth=0.25, relheight=0.48)
  1314. enter.place(relx=0.30, rely=0.2, relwidth=0.60, relheight=0.48)
  1315. for btn, text, func in zip(self.btn,
  1316. ["通过条件更新", "通过垃圾袋ID更新"],
  1317. [self.update_by_where, self.update_by_gid]):
  1318. btn['font'] = btn_font
  1319. btn['bg'] = Config.tk_btn_bg
  1320. btn['text'] = text
  1321. btn['command'] = func
  1322. self.btn[0].place(relx=0.55, rely=0.38, relwidth=0.25, relheight=0.08)
  1323. self.btn[1].place(relx=0.55, rely=0.78, relwidth=0.25, relheight=0.08)
  1324. def update_by_gid(self):
  1325. gid = self.enter.get()
  1326. check = (self.var[1].get() == 1)
  1327. event = tk_event.UpdateGarbageCheckEvent(self.station).start(check, f"GarbageID={gid}")
  1328. self.station.push_event(event)
  1329. def update_by_where(self):
  1330. where = self.where_enter.get()
  1331. check = (self.where_var[1].get() == 1)
  1332. event = tk_event.UpdateGarbageCheckEvent(self.station).start(check, where)
  1333. self.station.push_event(event)
  1334. def set_disable(self):
  1335. set_tk_disable_from_list(self.btn)
  1336. self.enter['state'] = 'disable'
  1337. self.where_enter['state'] = 'normal'
  1338. def reset_disable(self):
  1339. set_tk_disable_from_list(self.btn, flat='normal')
  1340. self.enter['state'] = 'normal'
  1341. self.where_enter['state'] = 'normal'
  1342. all_program = [WelcomeProgram, CreateNormalUserProgram, CreateManagerUserProgram, CreateAutoNormalUserProgram,
  1343. CreateGarbageProgram, DeleteUserProgram, DeleteUsersProgram, DeleteGarbageProgram,
  1344. DeleteGarbageMoreProgram, DeleteAllGarbageProgram, SearchUserProgram, SearchUserAdvancedProgram,
  1345. SearchGarbageProgram, SearchGarbageAdvancedProgram, SearchAdvancedProgram, UpdateUserScoreBase,
  1346. UpdateUserReputationBase, UpdateGarbageTypeProgram, UpdateGarbageCheckResultProgram,
  1347. ExportGarbageProgram, ExportUserProgram, CreateUserFromCSVProgram, AboutProgram]