v2.5更新
This commit is contained in:
@@ -161,7 +161,8 @@ class ConductModel:
|
||||
student_id: int = None,
|
||||
include_revoked: bool = True,
|
||||
related_type: str = None,
|
||||
reason_prefix: str = None
|
||||
reason_prefix: str = None,
|
||||
is_revoked: int = None
|
||||
) -> List[Dict[str, Any]]:
|
||||
"""获取所有记录(班主任/班长专用)"""
|
||||
# 空字符串转为None
|
||||
@@ -206,6 +207,10 @@ class ConductModel:
|
||||
sql += " AND cr.reason LIKE %s"
|
||||
params.append(f"{reason_prefix}%")
|
||||
|
||||
if is_revoked is not None:
|
||||
sql += " AND cr.is_revoked = %s"
|
||||
params.append(1 if is_revoked else 0)
|
||||
|
||||
sql += " ORDER BY cr.created_at DESC LIMIT %s OFFSET %s"
|
||||
params.extend([limit, offset])
|
||||
|
||||
|
||||
@@ -76,6 +76,12 @@ class SubjectModel:
|
||||
|
||||
@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"
|
||||
result = await execute_update(sql, (subject_id,))
|
||||
return result > 0
|
||||
|
||||
@@ -319,7 +319,8 @@ async def get_conduct_history(
|
||||
end_date: Optional[str] = None,
|
||||
grouped: bool = Query(False),
|
||||
related_type: Optional[str] = None,
|
||||
reason_prefix: Optional[str] = None
|
||||
reason_prefix: Optional[str] = None,
|
||||
is_revoked: Optional[int] = None
|
||||
):
|
||||
"""获取操行分历史记录"""
|
||||
try:
|
||||
@@ -335,7 +336,8 @@ async def get_conduct_history(
|
||||
end_date=end_date,
|
||||
grouped=grouped,
|
||||
related_type=related_type,
|
||||
reason_prefix=reason_prefix
|
||||
reason_prefix=reason_prefix,
|
||||
is_revoked=is_revoked
|
||||
)
|
||||
return success_response(data=result)
|
||||
except Exception as e:
|
||||
@@ -343,6 +345,86 @@ async def get_conduct_history(
|
||||
return error_response(message=f"获取历史记录失败: {str(e)}")
|
||||
|
||||
|
||||
@router.post("/conduct/batch-revoke")
|
||||
async def batch_revoke_conduct_records(request: Request):
|
||||
"""批量撤销操行分记录"""
|
||||
try:
|
||||
user = await get_current_user(request)
|
||||
if user["user_type"] != "admin":
|
||||
return error_response(message="无权进行此操作", code=403)
|
||||
|
||||
body = await request.json()
|
||||
record_ids = body.get("record_ids", [])
|
||||
if not record_ids or not isinstance(record_ids, list):
|
||||
return error_response(message="请提供要撤销的记录ID列表", code=400)
|
||||
if len(record_ids) > 100:
|
||||
return error_response(message="单次最多撤销100条记录", code=400)
|
||||
|
||||
success_count = 0
|
||||
fail_count = 0
|
||||
errors = []
|
||||
|
||||
for record_id in record_ids:
|
||||
result = await ConductService.revoke_record(
|
||||
record_id=record_id,
|
||||
revoker_id=user["user_id"]
|
||||
)
|
||||
if result["success"]:
|
||||
success_count += 1
|
||||
else:
|
||||
fail_count += 1
|
||||
errors.append({"record_id": record_id, "error": result["message"]})
|
||||
|
||||
return success_response(data={
|
||||
"success_count": success_count,
|
||||
"fail_count": fail_count,
|
||||
"errors": errors
|
||||
}, message=f"批量撤销完成: {success_count}条成功, {fail_count}条失败")
|
||||
except Exception as e:
|
||||
logger.error(f"批量撤销失败: {e}", exc_info=True)
|
||||
return error_response(message=f"批量撤销失败: {str(e)}")
|
||||
|
||||
|
||||
@router.post("/conduct/batch-restore")
|
||||
async def batch_restore_conduct_records(request: Request):
|
||||
"""批量反撤销操行分记录"""
|
||||
try:
|
||||
user = await get_current_user(request)
|
||||
if user["user_type"] != "admin":
|
||||
return error_response(message="无权进行此操作", code=403)
|
||||
|
||||
body = await request.json()
|
||||
record_ids = body.get("record_ids", [])
|
||||
if not record_ids or not isinstance(record_ids, list):
|
||||
return error_response(message="请提供要反撤销的记录ID列表", code=400)
|
||||
if len(record_ids) > 100:
|
||||
return error_response(message="单次最多反撤销100条记录", code=400)
|
||||
|
||||
success_count = 0
|
||||
fail_count = 0
|
||||
errors = []
|
||||
|
||||
for record_id in record_ids:
|
||||
result = await ConductService.restore_record(
|
||||
record_id=record_id,
|
||||
restorer_id=user["user_id"]
|
||||
)
|
||||
if result["success"]:
|
||||
success_count += 1
|
||||
else:
|
||||
fail_count += 1
|
||||
errors.append({"record_id": record_id, "error": result["message"]})
|
||||
|
||||
return success_response(data={
|
||||
"success_count": success_count,
|
||||
"fail_count": fail_count,
|
||||
"errors": errors
|
||||
}, message=f"批量反撤销完成: {success_count}条成功, {fail_count}条失败")
|
||||
except Exception as e:
|
||||
logger.error(f"批量反撤销失败: {e}", exc_info=True)
|
||||
return error_response(message=f"批量反撤销失败: {str(e)}")
|
||||
|
||||
|
||||
|
||||
# ========== 考勤管理 ==========
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ import re
|
||||
logger = setup_logger()
|
||||
router = APIRouter()
|
||||
|
||||
# 版本列表(按顺序)
|
||||
# 版本列表(按顺序)
|
||||
ALL_VERSIONS = {
|
||||
'1.0': 'v1.0.sql',
|
||||
@@ -35,7 +34,9 @@ ALL_VERSIONS = {
|
||||
'2.1': 'v2.1.sql',
|
||||
'2.2': 'v2.2.sql',
|
||||
'2.3': 'v2.3.sql',
|
||||
'2.3': 'v2.3.sql',
|
||||
'2.4': 'v2.4.sql',
|
||||
'2.5': 'v2.5.sql',
|
||||
}
|
||||
|
||||
# 版本特征标记(按优先级从高到低)
|
||||
|
||||
@@ -213,7 +213,8 @@ class ConductService:
|
||||
end_date: Optional[str] = None,
|
||||
grouped: bool = False,
|
||||
related_type: Optional[str] = None,
|
||||
reason_prefix: Optional[str] = None
|
||||
reason_prefix: Optional[str] = None,
|
||||
is_revoked: Optional[int] = None
|
||||
) -> Dict[str, Any]:
|
||||
"""获取历史记录"""
|
||||
# 空字符串转为None
|
||||
@@ -251,7 +252,8 @@ class ConductService:
|
||||
end_date=end_date,
|
||||
student_id=student_id,
|
||||
related_type=related_type,
|
||||
reason_prefix=reason_prefix
|
||||
reason_prefix=reason_prefix,
|
||||
is_revoked=is_revoked
|
||||
)
|
||||
|
||||
# 获取总数
|
||||
@@ -273,6 +275,9 @@ class ConductService:
|
||||
if reason_prefix:
|
||||
count_conditions.append("cr.reason LIKE %s")
|
||||
count_params.append(f"{reason_prefix}%")
|
||||
if is_revoked is not None:
|
||||
count_conditions.append("cr.is_revoked = %s")
|
||||
count_params.append(1 if is_revoked else 0)
|
||||
count_where = " AND ".join(count_conditions)
|
||||
count_sql = f"""
|
||||
SELECT COUNT(*) as total FROM conduct_records cr
|
||||
|
||||
Reference in New Issue
Block a user