Browse Source

fix: 修复了一些Bug

SongZihuan 3 years ago
parent
commit
23e6218ba3

+ 16 - 3
app/data/views.py

@@ -23,6 +23,9 @@ def index():
 
 @data.route('/pyecharts/count_by_day')
 def count_by_days():
+    """
+    时段统计分析
+    """
     db_data = views.website.count_by_days()
     if db_data is None:
         abort(500)
@@ -53,6 +56,11 @@ def count_by_days():
 
 
 def count_by_date__(days):
+    """
+    日期统计分析
+    :param days: 7日 30日
+    :return:
+    """
     if days != 7 and days != 30:
         abort(404)
 
@@ -61,7 +69,6 @@ def count_by_date__(days):
         abort(500)
 
     line = pyecharts.charts.Line(init_opts=init_opts)
-    print(db_data)
     res = {}
     loc_type = []
     count_data = [0] * days
@@ -94,6 +101,9 @@ def count_by_date__(days):
 @data.route('/pyecharts/count_by_date/<int:days>')
 def count_by_date(days):
     if days == 307:
+        """
+        将30日和7日统计汇聚在一张表中
+        """
         line7 = count_by_date__(7)
         line30 = count_by_date__(30)
         chart = pyecharts.charts.Tab("时间统计")
@@ -106,6 +116,9 @@ def count_by_date(days):
 
 @data.route('/pyecharts/count_passing_rate')
 def count_passing_rate():
+    """
+    通过率统计
+    """
     rate_list = views.website.count_passing_rate()
     if rate_list is None:
         abort(500)
@@ -118,14 +131,14 @@ def count_passing_rate():
         name = GarbageType.GarbageTypeStrList_ch[int(i[0].decode("utf-8"))]
         pie = pyecharts.charts.Pie(init_opts=init_opts)
         pie.set_global_opts(xaxis_opts=xaxis_opts, title_opts=pyecharts.options.TitleOpts(title=f"{name}-通过率"))
-        pie.add(series_name=name, data_pair=[("通过", i[1]), ("不通过", 1 - i[1])], color=random_color())
+        pie.add(series_name=name, data_pair=[("通过", i[1]), ("不通过", 1 - i[1])])
         page.add(pie, f"{name}-通过率")
         rate_global += i[1]
 
     rate_global = rate_global / 4
     pie = pyecharts.charts.Pie(init_opts=init_opts)
     pie.set_global_opts(xaxis_opts=xaxis_opts, title_opts=pyecharts.options.TitleOpts(title="平均-通过率"))
-    pie.add(series_name="平均", data_pair=[("通过", rate_global), ("不通过", 1 - rate_global)], color=random_color())
+    pie.add(series_name="平均", data_pair=[("通过", rate_global), ("不通过", 1 - rate_global)])
     page.add(pie, "平均-通过率")
 
     return Markup(page.render_embed())

+ 1 - 1
app/index/views.py

@@ -8,7 +8,7 @@ app: Optional[Flask] = None
 @hello.route('/')
 def start():
     """
-    显示 start 宇宙界面
+    显示 start 樱花界面
     """
     return render_template("hello/start.html")
 

+ 7 - 0
app/news/views.py

@@ -57,6 +57,10 @@ def index():
 
 
 def manager_required(f):
+    """
+    检查是否有管理员权限
+    """
+
     @functools.wraps(f)
     def func(*args, **kwargs):
         if not current_user.is_manager():
@@ -70,6 +74,9 @@ def manager_required(f):
 @login_required
 @manager_required
 def delete():
+    """
+    管理员: 删除内容
+    """
     context_id = request.args.get("context")
     if context_id is None:
         abort(404)

+ 6 - 0
app/rank/views.py

@@ -8,6 +8,9 @@ app: Optional[Flask] = None
 
 @rank.route('/up')
 def rank_up():
+    """
+    高分榜 正向排行
+    """
     try:
         page = int(request.args.get("page", 1))
     except (ValueError, TypeError):
@@ -20,6 +23,9 @@ def rank_up():
 
 @rank.route('/down')
 def rank_down():
+    """
+    警示榜 反向排行
+    """
     try:
         page = int(request.args.get("page", 1))
     except (ValueError, TypeError):

+ 15 - 1
app/store/views.py

@@ -17,11 +17,17 @@ app: Optional[Flask] = None
 
 
 class BuySetForm(FlaskForm):
+    """
+    兑换/库存设定/积分设定表单
+    """
     quantity = TextField(validators=[DataRequired(message="请输入数量")])
     submit = SubmitField()
 
 
 class AddNewGoodsForm(FlaskForm):
+    """
+    新增商品表单
+    """
     name = TextField(validators=[DataRequired(message="请输入名字")])
     quantity = TextField(validators=[DataRequired(message="请输入库存")])
     score = TextField(validators=[DataRequired(message="请输入库存")])
@@ -77,6 +83,11 @@ def buy(goods_id: int):
 
 
 def manager_required(f):
+    """
+    管理员权限
+    :return:
+    """
+
     @functools.wraps(f)
     def func(*args, **kwargs):
         if not current_user.is_manager():
@@ -151,7 +162,7 @@ def confirm(token):
     确认取件
     """
     try:
-        s = Serializer(Config.passwd_salt, expires_in=3600)  # 3h有效
+        s = Serializer(Config.passwd_salt)
         data = s.loads(token)
         order = data["order"]
         user = data["uid"]
@@ -168,6 +179,9 @@ def confirm(token):
 @login_required
 @manager_required
 def add_new_goods():
+    """
+    新增新商品
+    """
     form = AddNewGoodsForm()
     if form.validate_on_submit():
         name = form.name.data

+ 1 - 1
app/templates/base.html

@@ -44,7 +44,7 @@
                 高分榜 </a></li>
 
             <li class="nav-top-item"><a class="nav-top-item" href="{{ url_for('rank.rank_down', page=1) }}">
-                警榜 </a></li>
+                警榜 </a></li>
 
             <li class="nav-top-item"><a class="nav-top-item" href="{{ url_for('store.index') }}">
                 积分商城 </a></li>

+ 4 - 4
app/templates/store/store_macro.html

@@ -1,18 +1,18 @@
 {% macro _get_store_item(infos, store_form, user) %}
-    {% if user.is_manager or infos[2] > 0 %}
+    {% if user.is_manager() or infos[2] > 0 %}
         <section id="store-item">
             <p class="store-item-info store-item-title"> {{ infos[0] }} </p>
             <p class="store-item-info"> 消耗 {{ infos[1] }} 积分</p>
             <p class="store-item-info"> 剩余 {{ infos[2] }} 件 </p>
             <hr>
             <form
-                    {% if user.is_manager %}
+                    {% if user.is_manager() %}
                         action="{{ url_for("store.set_goods", goods_id=infos[3]) }}"
                     {% else %}
                         action="{{ url_for("store.buy", goods_id=infos[3]) }}"
                     {% endif %} method="post">
                 {{ store_form.hidden_tag() }}
-                {% if user.is_manager %}
+                {% if user.is_manager() %}
                     <label class="store-item-num">
                         库存:
                         {{ store_form.quantity(type="number", class="store-item-num", placeholder="库存", value=infos[2]) }}
@@ -26,7 +26,7 @@
                     {{ store_form.submit(value="兑换", class="store-item-submit") }}
                 {% endif %}
             </form>
-            {% if user.is_manager %}
+            {% if user.is_manager() %}
                 <hr>
                 <form action="{{ url_for("store.set_goods_score", goods_id=infos[3]) }}" method="post">
                     {{ store_form.hidden_tag() }}

+ 8 - 0
app/web.py

@@ -44,6 +44,7 @@ class WebsiteBase:
 
 
 class AuthWebsite(WebsiteBase):
+    """ 用户界面 """
     def load_user_by_name(self, name: uname_t, passwd: passwd_t) -> Optional["web_user.WebUser"]:
         user = find_user_by_name(name, passwd, self._db)
         if user is None:
@@ -89,6 +90,7 @@ class AuthWebsite(WebsiteBase):
 
 
 class StoreWebsite(WebsiteBase):
+    """ 积分商城 """
     def get_store_list(self) -> Optional[List]:
         return get_store_item_list(self._db)
 
@@ -122,6 +124,7 @@ class StoreWebsite(WebsiteBase):
 
 
 class RankWebsite(WebsiteBase):
+    """ 排行榜 """
     def get_rank(self, page: int, order_by: str = "DESC", url: str = "rank_up"):
         count = math.ceil(count_all_user(self._db) / 20)
         offset = 20 * (page - 1)
@@ -129,6 +132,7 @@ class RankWebsite(WebsiteBase):
 
 
 class NewsWebsite(WebsiteBase):
+    """ 博客 """
     def write_news(self, context: str, uid: uid_t):
         return write_news(context, uid, self.db)
 
@@ -146,6 +150,10 @@ class NewsWebsite(WebsiteBase):
 
 
 class DataWebsite(WebsiteBase):
+    """
+    数据分析
+    """
+
     def count_by_days(self):
         cur = self._db.search(columns=["GarbageType", "DATE_FORMAT(UseTime,'%H') AS days", "count(GarbageID) AS count"],
                               table="garbage",

+ 2 - 0
app/web_goods.py

@@ -8,6 +8,7 @@ from . import web_user
 
 
 class Goods:
+    """ 商品 """
     def __init__(self, name: str, score: score_t, quantity: int, goods_id: int):
         self._name = name
         self._quantity = quantity
@@ -15,6 +16,7 @@ class Goods:
         self._id = goods_id
 
     def buy_for_user(self, quantity: int, user_: web_user.WebUser) -> Tuple[int, int]:
+        """ 兑换商品 """
         score_ = quantity * self._score
         if quantity > self._quantity or quantity <= 0:
             return -2, 0  # 数量错误

+ 3 - 1
app/web_user.py

@@ -11,6 +11,7 @@ from . import views
 
 
 class WebAnonymous(AnonymousUserMixin):
+    """ 网页匿名用户 """
     def __init__(self):
         self.group = "匿名用户"
         self.score = "0"
@@ -52,6 +53,7 @@ class WebAnonymous(AnonymousUserMixin):
 
 
 class WebUser(UserMixin):
+    """ 网页用户 """
     def __init__(self, name: uname_t, passwd: passwd_t = None, uid: uid_t = None):
         super(WebUser, self).__init__()
         self._name = name
@@ -118,7 +120,7 @@ class WebUser(UserMixin):
         return self.group == "管理员"
 
     def get_qr_code(self):
-        s = Serializer(Config.passwd_salt, expires_in=3600)  # 3h有效
+        s = Serializer(Config.passwd_salt, expires_in=3600)  # 1h有效
         token = s.dumps({"order": f"{self.order}", "uid": f"{self._uid}"})
         return self.order, self._uid, token
 

+ 1 - 3
conf/aliyun.py

@@ -2,9 +2,7 @@ from . import args
 
 
 class ConfigAliyunRelease:
-    """
-    阿里云 SDK 相关配置
-    """
+    """ 阿里云 SDK 相关配置 """
     aliyun_key = args.p_args['aliyun_key']
     aliyun_secret = args.p_args['aliyun_secret']
     aliyun_region_id = "cn-shanghai"

+ 1 - 0
conf/equipment.py

@@ -1,4 +1,5 @@
 class ConfigCaptureRelease:
+    """ 摄像头相关配置 """
     capture_num = 0  # 摄像头号
     capture_arg = []
 

+ 1 - 0
conf/matplotlib_conf.py

@@ -1,4 +1,5 @@
 class ConfigMatplotlibRelease:
+    """ Matplotlib 相关配置 """
     matplotlib_font = "SimHei"
     matplotlib_font_dict = dict(family=matplotlib_font)
 

+ 1 - 0
conf/sql.py

@@ -2,6 +2,7 @@ from . import args
 
 
 class ConfigDatabaseRelease:
+    """ MySQL 相关配置 """
     database = 'MySQL'
     mysql_url = args.p_args['mysql_url']
     mysql_name = args.p_args['mysql_name']

+ 7 - 0
conf/sys_default.py

@@ -2,11 +2,13 @@ from .args import p_args
 
 
 class ConfigSecretRelease:
+    """ 加密相关配置 """
     passwd_salt = p_args['app_secret']
     wtf_secret = p_args['app_secret']
 
 
 class ConfUserRelease:
+    """ 用户信息相关配置 """
     default_score = 10
     default_reputation = 300
 
@@ -17,6 +19,8 @@ class ConfUserRelease:
 
 
 class ConfigSystemRelease:
+    """ 系统信息相关配置 """
+
     base_location = "KZ"
     search_reset_time = 10  # 搜索间隔的时间
     show_uid_len = 12  # 展示uid的长度
@@ -31,6 +35,8 @@ HGSSystem 版权归属 SuperHuan
 
 
 class ConfigSystemTest(ConfigSystemRelease):
+    """ 系统信息相关配置 """
+
     search_reset_time = 1  # 搜索间隔的时间
     about_info = f'''
 HGSSystem is Garbage Sorting System
@@ -44,6 +50,7 @@ HGSSystem 版权归属 SuperHuan
 
 
 class ConfigTkinterRelease:
+    """ tkinter 相关配置 """
     tk_refresh_delay = 50  # 延时任务的时间
 
     tk_second_win_bg = "#fffffb"  # tkinter 第二窗口 标准颜色

+ 3 - 0
core/garbage.py

@@ -6,8 +6,10 @@ from tool.location import HGSLocation, hgs_location_t
 
 
 class GarbageType:
+    # 类别从 1 开始计数
     GarbageTypeStrList: List = ["", "recyclable", "kitchen", "hazardous", "other"]
     GarbageTypeStrList_ch: List = ["", "可回收", "厨余", "有害", "其他"]
+
     recyclable: enum = 1
     kitchen: enum = 2
     hazardous: enum = 3
@@ -15,6 +17,7 @@ class GarbageType:
 
 
 class GarbageBag:
+    """垃圾袋"""
     def __init__(self, gid: gid_t):
         self._gid: gid_t = gid_t(gid)
         self._have_use: bool = False

+ 22 - 8
core/user.py

@@ -22,7 +22,7 @@ class User(metaclass=abc.ABCMeta):
         self._name: uname_t = uname_t(name)
         self._uid: uid_t = uid_t(uid)
         self._type: enum = enum(user_type)
-        self._lock = threading.RLock()
+        self._lock = threading.RLock()  # 用户 互斥锁
 
     def is_manager(self):
         try:
@@ -211,14 +211,21 @@ class NormalUser(User):
         return score
 
     def throw_rubbish(self, garbage: GarbageBag, garbage_type: enum, loc: location_t = Config.base_location) -> bool:
+        """
+        垃圾投放
+        :param garbage: 垃圾袋
+        :param garbage_type: 垃圾类别
+        :param loc: 地区
+        :return:
+        """
         try:
             self._lock.acquire()
-            if self._rubbish > Config.max_rubbish_week:
+            if self._rubbish > Config.max_rubbish_week:  # 大于上限, 扣分
                 self.add_score(-3)
-            elif self._rubbish > Config.limit_rubbish_week:
+            elif self._rubbish > Config.limit_rubbish_week:  # 大于最大上限, 不再允许扔垃圾
                 return False
 
-            if garbage.is_use() or garbage.is_check()[0]:
+            if garbage.is_use() or garbage.is_check()[0]:  # 垃圾袋被使用
                 return False
             garbage.config_use(garbage_type, HGSTime(), self._uid, loc)
 
@@ -235,16 +242,23 @@ class ManagerUser(User):
     def __init__(self, name: uname_t, uid: uid_t):
         super(ManagerUser, self).__init__(name, uid, UserType.manager)
 
-    def check_rubbish(self, garbage: GarbageBag, right: bool, user: User) -> bool:
+    def check_rubbish(self, garbage: GarbageBag, result: bool, user: User) -> bool:
+        """
+        检查垃圾
+        :param garbage: 垃圾袋
+        :param result: 结果
+        :param user: 垃圾袋投放者
+        :return:
+        """
         if (not garbage.is_use()) or garbage.is_check()[0] or user.get_uid() != garbage.get_user():  # 调用时已经有锁
             return False
 
         try:
             self._lock.acquire()
-            garbage.config_check(right, self._uid)
-            user.evaluate(right)
+            garbage.config_check(result, self._uid)
+            user.evaluate(result)
 
-            if right:
+            if result:
                 if garbage.get_type() == GarbageType.recyclable:
                     user.add_score(3)
                 elif garbage.get_type() == GarbageType.kitchen or garbage.get_type() == GarbageType.hazardous:

+ 1 - 0
equipment/aliyun.py

@@ -20,6 +20,7 @@ class AliyunServerException(ServerException):
 
 
 class Aliyun:
+    """ Aliyun SDK """
     def __init__(self,
                  key: Optional[str] = Config.aliyun_key,
                  secret: Optional[str] = Config.aliyun_secret,

+ 4 - 0
equipment/scan.py

@@ -8,6 +8,7 @@ from tool.typing import *
 
 
 class HGSCapture:
+    """ 摄像头扫描 """
     def __init__(self, capnum: int = Config.capture_num, *args, **kwargs):
         args = *args, *Config.capture_arg
         if cv2.CAP_DSHOW not in args:
@@ -17,6 +18,7 @@ class HGSCapture:
         self._lock = threading.RLock()
 
     def get_image(self):
+        """ 获取摄像头图像 """
         try:
             self._lock.acquire()
             ret, frame = self._capture.read()
@@ -27,6 +29,7 @@ class HGSCapture:
         return ret
 
     def get_frame(self):
+        """ 获取 frame """
         try:
             self._lock.acquire()
             frame = self._frame
@@ -63,6 +66,7 @@ class QRCode:
 
 
 class HGSQRCoder:
+    """ 二维码扫描仪 """
     def __init__(self, cap: HGSCapture):
         self._cap = cap
         self._last_qr: Optional[QRCode] = None

+ 19 - 5
sql/garbage.py

@@ -7,6 +7,13 @@ from core.garbage import GarbageBag, GarbageType
 
 
 def update_garbage_type(where: str, type_: int, db: DB) -> int:
+    """
+    更新垃圾袋类型
+    :param where: 条件
+    :param type_: 类型
+    :param db: 数据库
+    :return:
+    """
     if len(where) == 0:
         return -1
 
@@ -16,11 +23,18 @@ def update_garbage_type(where: str, type_: int, db: DB) -> int:
     return cur.rowcount
 
 
-def update_garbage_check(where: str, check_: bool, db: DB) -> int:
+def update_garbage_check(where: str, result: bool, db: DB) -> int:
+    """
+    更新垃圾袋检测结果
+    :param where: 条件
+    :param result: 结果
+    :param db: 数据库
+    :return:
+    """
     if len(where) == 0:
         return -1
 
-    i: str = '1' if check_ else '0'
+    i: str = '1' if result else '0'
     cur = db.update(table="garbage", kw={"CheckResult": i}, where=where)
     if cur is None:
         return -1
@@ -149,7 +163,7 @@ def get_garbage_by_uid(uid: uid_t, columns, limit, db: DB, offset: int = 0):
 def __find_garbage(columns: List[str], table: str, where: str, db: DB):
     cur = db.search(columns=columns, table=table, where=where)
     if cur is None or cur.rowcount == 0:
-        return [None, tuple()]
+        return None, tuple()
     assert cur.rowcount == 1
     res = cur.fetchone()
     assert len(res) == len(columns)
@@ -169,7 +183,7 @@ def find_wait_garbage(gid: gid_t, db: DB) -> Union[GarbageBag, None]:
     gb, res = __find_garbage(columns=["GarbageID", "GarbageType", "UseTime", "UserID", "Location"],
                              table="garbage_c",
                              where=f"GarbageID = {gid}",
-                             db=db)[0]
+                             db=db)
     if gb is None:
         return None
 
@@ -189,7 +203,7 @@ def find_use_garbage(gid: gid_t, db: DB) -> Union[GarbageBag, None]:
                                       "CheckResult", "CheckerID"],
                              table="garbage_u",
                              where=f"GarbageID = {gid}",
-                             db=db)[0]
+                             db=db)
     if gb is None:
         return None
 

+ 5 - 5
sql/user.py

@@ -167,9 +167,9 @@ def get_user_phone(uid: uid_t, db: DB) -> Optional[str]:
 
 def del_user(uid: uid_t, db: DB) -> bool:
     cur = db.search(columns=["GarbageID"], table="garbage_time", where=f"UserID = '{uid}'")  # 确保没有引用
-
-    if cur is None or cur.rowcount != 0:
+    if cur is None or cur.rowcount == 0:
         return False
+
     cur = db.delete(table="user", where=f"UserID = '{uid}'")
     if cur is None or cur.rowcount == 0:
         return False
@@ -185,9 +185,9 @@ def del_user_from_where_scan(where: str, db: DB) -> int:
 
 
 def del_user_from_where(where: str, db: DB) -> int:
-    cur = db.search(columns=["GarbageID"], table="garbage_time", where=where)  # 确保没有引用
-    if cur is None or cur.rowcount != 0:
-        return False
+    cur = db.search(columns=["UserID"], table="user", where=where)  # 确保没有引用
+    if cur is None or cur.rowcount == 0:
+        return 0
     cur = db.delete(table="user", where=where)
     if cur is None:
         return -1

+ 2 - 2
steup.py

@@ -151,7 +151,7 @@ def write_bat():
 if "%1" == "h" goto begin
 mshta vbscript:createobject("wscript.shell").run("""%~nx0"" h",0)(window.close)&&exit
 :begin\n''')  # 隐藏 cmd 的命令
-            f.write(f"{python} {main} --program {i}")
+            f.write(f"{python} {main} --program {i} --run release")
 
 
 def write_shell():
@@ -160,7 +160,7 @@ def write_shell():
         bat = os.path.join(install_prefix, f"{i}_HGSSystem.sh")
         print(f"创建shell脚本 {bat}")
         with open(bat, "w") as f:
-            f.write(f"{python} {main} -- program {i}")
+            f.write(f"{python} {main} --program {i} --run release")
 
 
 install_base()

+ 30 - 10
tk_ui/admin_event.py

@@ -255,7 +255,7 @@ class DelUserFromWhereEvent(AdminEventBase):
         if res != -1:
             self.station.show_msg("扫描结果", f"成功删除{res}个用户")
         else:
-            self.station.show_warning("扫描结果", f"获取扫描结果失败")
+            self.station.show_warning("扫描结果", f"删除用户失败")
 
 
 class DelGarbageEvent(AdminEventBase):
@@ -424,14 +424,18 @@ class SearchUserAdvancedEvent(AdminEventBase):
             self.program.view.insert('', 'end', values=i)
 
 
-def set_garbage_search_result(i):
-    i = list(i)
-    if i[-1] is not None:
-        i[-1] = "投放正确" if i[-1] == DBBit.BIT_1 else "投放错误"
-    if i[-2] is not None:
-        tmp: bytes = i[-2]
-        i[-2] = GarbageType.GarbageTypeStrList_ch[int(tmp.decode('utf-8'))]
-    return i
+def set_garbage_search_result(data):
+    data = list(data)
+    if data[6] is not None:
+        tmp: bytes = data[6]
+        data[6] = GarbageType.GarbageTypeStrList_ch[int(tmp.decode('utf-8'))]
+    if data[7] is not None:
+        data[7] = "投放正确" if data[7] == DBBit.BIT_1 else "投放错误"
+
+    for index, i in enumerate(data):
+        if i is None:
+            data[index] = "无"
+    return data
 
 
 class SearchGarbageEvent(AdminEventBase):
@@ -484,6 +488,22 @@ class SearchGarbageAdvancedEvent(AdminEventBase):
             self.program.view.insert('', 'end', values=i)
 
 
+def set_advanced_search_result(data):
+    data = list(data)
+    if data[-2] is not None:
+        tmp: bytes = data[-2]
+        data[-2] = GarbageType.GarbageTypeStrList_ch[int(tmp.decode('utf-8'))]
+
+    if data[-1] is not None:
+        data[-1] = "投放正确" if data[-1] == DBBit.BIT_1 else "投放错误"
+
+    data = list(data)
+    for index, i in enumerate(data):
+        if i is None:
+            data[index] = "无"
+    return data
+
+
 class SearchAdvancedEvent(AdminEventBase):
     def func(self, columns, sql):
         return self.station.search_advanced(columns, sql)
@@ -505,7 +525,7 @@ class SearchAdvancedEvent(AdminEventBase):
         for i in self.program.view.get_children():
             self.program.view.delete(i)
         for i in res:
-            i = set_garbage_search_result(i)
+            i = set_advanced_search_result(i)
             self.program.view.insert('', 'end', values=i)
 
 

+ 17 - 3
tk_ui/admin_program.py

@@ -103,8 +103,6 @@ HGSSystem 管理者界面:
 
 系统登录:
   1) 仅Manager用户可以登录
-
-关于彩蛋: 存在
                 '''.strip())
 
         self.title.place(relx=0.1, rely=0.0, relwidth=0.8, relheight=0.2)
@@ -523,12 +521,20 @@ class ExportGarbageProgram(ExportProgramBase):
     def export_id(self):
         gid = self.gid_var[0].get()
         path = self.gid_var[1].get()
+        if len(path) == 0:
+            self.station.show_warning("导出失败", "请指定导出的位置")
+            return
+
         event = tk_event.ExportGarbageByIDEvent(self.station).start(path, gid)
         self.station.push_event(event)
 
     def export_where(self):
         where = self.where_var[0].get()
         path = self.where_var[1].get()
+        if len(path) == 0:
+            self.station.show_warning("导出失败", "请指定导出的位置")
+            return
+
         event = tk_event.ExportGarbageAdvancedEvent(self.station).start(path, where)
         self.station.push_event(event)
 
@@ -542,12 +548,20 @@ class ExportUserProgram(ExportProgramBase):
     def export_id(self):
         uid = self.gid_var[0].get()
         path = self.gid_var[1].get()
+        if len(path) == 0:
+            self.station.show_warning("导出失败", "请指定导出的位置")
+            return
+
         event = tk_event.ExportUserByIDEvent(self.station).start(path, uid)
         self.station.push_event(event)
 
     def export_where(self):
         where = self.where_var[0].get()
         path = self.where_var[1].get()
+        if len(path) == 0:
+            self.station.show_warning("导出失败", "请指定导出的位置")
+            return
+
         event = tk_event.ExportUserAdvancedEvent(self.station).start(path, where)
         self.station.push_event(event)
 
@@ -1884,7 +1898,7 @@ class StatisticsTimeProgramBase(AdminProgram):
         self.hide_list_tk['activestyle'] = tk.NONE
 
         for btn, text, func, x in zip([self.btn_show, self.btn_hide],
-                                      ["Show", "Hide"],
+                                      ["显示", "隐藏"],
                                       [self.show, self.hide],
                                       [0.00, 0.50]):
             btn['font'] = little_btn_font

+ 3 - 2
tk_ui/station.py

@@ -91,8 +91,9 @@ class GarbageStationBase(TkEventMain, metaclass=abc.ABCMeta):
         if self._user is None:
             return False
         if not self._user.is_manager() and time.time() - self._user_last_time > 20:
+            self.show_msg("退出登录", "用户自动退出", show_time=3.0)
             self._user = None
-            return False
+            raise Exception
         return True
 
     def __check_normal_user(self):
@@ -1214,7 +1215,7 @@ class GarbageStation(GarbageStationBase):
         rubbish: tk.Variable = self._user_rubbish[2]
         eval_: tk.Variable = self._user_eval[2]
 
-        user_info: Dict[str, str] = self.get_user_info_no_update()
+        user_info: Dict[str, str] = self.get_user_info_no_update()  # 此处检查用户是否过期登录
         if user_info.get('uid') is None:
             name.set('未登录')
             uid.set('未登录')

+ 6 - 6
tk_ui/station_event.py

@@ -86,17 +86,17 @@ class ScanGarbageEvent(StationEventBase):
         return self.thread is not None and not self.thread.is_alive()
 
     def done_after_event(self):
-        self.thread.join()
-        if self.thread.result is not None:
+        res = self.thread.wait_event()
+        if res is not None:
             if self._user is None:
-                self.station.show_warning("操作失败", "垃圾袋已经被使用")
+                self.station.show_warning("操作失败", "用户未登录")
             elif self._user.is_manager():
-                self.station.to_get_garbage_check(self.thread.result)
+                self.station.to_get_garbage_check(res)
                 self.station.show_garbage_info()  # 显示信息
                 self.station.update_control()
             else:
-                self.station.to_get_garbage_type(self.thread.result)
-                self.station.hide_msg_rank()  # 如果有msg也马上隐藏
+                self.station.to_get_garbage_type(res)
+                self.station.show_msg("扫码垃圾袋", "垃圾袋扫描成功", show_time=3)
                 self.station.update_control()