diff --git a/backend/models/subject.py b/backend/models/subject.py index 16b06d1..62a3b47 100644 --- a/backend/models/subject.py +++ b/backend/models/subject.py @@ -71,18 +71,18 @@ class SubjectModel: @staticmethod async def has_related_data(subject_id: int) -> bool: - """检查科目是否有关联数据""" - return False + """检查科目是否有关联的作业数据""" + sql = "SELECT COUNT(*) AS cnt FROM assignments WHERE subject_id = %s" + result = await execute_one(sql, (subject_id,)) + return result and result.get("cnt", 0) > 0 @staticmethod async def delete(subject_id: int) -> bool: - """软删除科目(设置 is_active = 0),如果已禁用也返回成功""" + """真正删除科目记录""" subject = await SubjectModel.get_by_id(subject_id) if not subject: return False - if subject.get("is_active") == 0: - return True # 已禁用,视为成功 - sql = "UPDATE subjects SET is_active = 0 WHERE subject_id = %s" + sql = "DELETE FROM subjects WHERE subject_id = %s" result = await execute_update(sql, (subject_id,)) return result > 0 diff --git a/backend/services/subject_service.py b/backend/services/subject_service.py index 2ab56cd..7743050 100644 --- a/backend/services/subject_service.py +++ b/backend/services/subject_service.py @@ -67,7 +67,7 @@ class SubjectService: @staticmethod async def delete_subject(subject_id: int) -> Dict[str, Any]: - """删除科目(软删除)""" + """删除科目(真正删除记录)""" # 检查科目是否有关联数据 has_data = await SubjectModel.has_related_data(subject_id) if has_data: @@ -76,7 +76,7 @@ class SubjectService: result = await SubjectModel.delete(subject_id) if result: - logger.info(f"禁用科目: {subject_id}") + logger.info(f"删除科目: {subject_id}") return {"success": True} else: - return {"success": False, "message": "禁用科目失败"} \ No newline at end of file + return {"success": False, "message": "删除科目失败"} \ No newline at end of file diff --git a/frontend/assets/css/style.css b/frontend/assets/css/style.css index 9f336da..7a847d5 100644 --- a/frontend/assets/css/style.css +++ b/frontend/assets/css/style.css @@ -853,10 +853,6 @@ tr:hover { .action-dropdown-menu { display: none; - position: absolute; - bottom: 100%; - right: 0; - margin-bottom: 4px; background: white; border-radius: 8px; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12); @@ -899,12 +895,6 @@ tr:hover { color: var(--color-danger-dark); } -@media (max-width: 768px) { - .action-dropdown-menu { - right: auto; - left: 0; - } -} /* ========== 链接 ========== */ .link { @@ -937,11 +927,11 @@ tr:hover { vertical-align: top; } -/* 原因列:每行最少7个字,自动换行 */ -.history-reason { +/* 原因列:每行最少7个字,自动换行(使用td前缀提升优先级,防止被preserve-newlines覆盖) */ +td.history-reason { min-width: 7em; max-width: 200px; - white-space: normal; + white-space: normal !important; word-break: break-word; line-height: 1.5; vertical-align: top; diff --git a/frontend/assets/js/common.js b/frontend/assets/js/common.js index d6c3e22..22321dd 100644 --- a/frontend/assets/js/common.js +++ b/frontend/assets/js/common.js @@ -359,6 +359,8 @@ function closeAllDropdowns() { m.style.position = ''; m.style.left = ''; m.style.top = ''; + m.style.bottom = ''; + m.style.right = ''; m.style.transform = ''; var toggle = m.closest('.action-dropdown'); if (toggle) {