refactor: P4c 批次1 服务层改造(notice/param/link/level)
【服务层新范式批量铺开】4 个 uniform 模块: - service:get_x_page(params)->dict、add/update/status(data)->None、 delete(ids)->int、get_info 委托 Repository(新建 repository.py) - 业务失败 raise BizError;router 取参包 R - level 的 Excel import/export 暂保留 R 返回(后续统一改造) 【工具】codemod 函数级转换(try/except 退格移除、R.failed→BizError、 R.ok→return data)+ black 格式化 + 未用导入清理 【教训】清理脚本 startswith 前缀误删含多名字的 import 行(models_to_list, model_to_dict 同行)导致 F821,已按 F821 精确补回 【验收】应用启动;4 服务分页查询运行时正常;12 passed;flake8 零告警 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude
parent
63afa4e629
commit
3f55f62f0d
@@ -50,7 +50,6 @@ from src.common.base_db import BaseDB
|
||||
from src.common.base_model import BaseModel
|
||||
from config import DB_PREFIX
|
||||
from src.core.database import db
|
||||
from src.common.utils.case_converter import convert_camel_to_snake
|
||||
|
||||
|
||||
# ============================================================
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
"""
|
||||
Link 仓储模块
|
||||
=============================================================
|
||||
|
||||
数据访问层,继承 BaseRepository 获得通用 CRUD 能力。
|
||||
"""
|
||||
|
||||
from src.common.base_repository import BaseRepository
|
||||
from src.modules.cms.link.models import Link
|
||||
|
||||
|
||||
class LinkRepository(BaseRepository):
|
||||
"""Link 仓储"""
|
||||
|
||||
model = Link
|
||||
@@ -55,22 +55,24 @@
|
||||
application.middleware.check_permission - 权限校验中间件
|
||||
"""
|
||||
|
||||
from flask import Blueprint
|
||||
from flask import Blueprint, request
|
||||
|
||||
from application.middleware.check_demo import check_demo
|
||||
from application.middleware.check_permission import check_permission
|
||||
from src.modules.cms.link import service as link
|
||||
from src.common.utils.request import parse_batch_ids
|
||||
link_blue = Blueprint('link', __name__, url_prefix='/link')
|
||||
from src.common.utils.request import parse_batch_ids, parse_request_body
|
||||
|
||||
from src.core import response as R
|
||||
|
||||
link_blue = Blueprint("link", __name__, url_prefix="/link")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 友链分页查询
|
||||
# ============================================================
|
||||
|
||||
@link_blue.route('/page', methods=["GET"])
|
||||
|
||||
@link_blue.route("/page", methods=["GET"])
|
||||
@check_permission("sys:link:page")
|
||||
def page():
|
||||
"""
|
||||
@@ -82,15 +84,15 @@ def page():
|
||||
Returns:
|
||||
JSON: 友链分页数据,包含 records(数据列表)、total(总记录数)等
|
||||
"""
|
||||
result = link.get_link_page()
|
||||
return result
|
||||
return R.ok(data=link.get_link_page(request.args))
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 友链详情查询
|
||||
# ============================================================
|
||||
|
||||
@link_blue.route('/detail/<int:id>', methods=["GET"])
|
||||
|
||||
@link_blue.route("/detail/<int:id>", methods=["GET"])
|
||||
@check_permission("sys:link:detail")
|
||||
def detail(id):
|
||||
"""
|
||||
@@ -110,7 +112,8 @@ def detail(id):
|
||||
# 友链添加
|
||||
# ============================================================
|
||||
|
||||
@link_blue.route('/add', methods=["POST"])
|
||||
|
||||
@link_blue.route("/add", methods=["POST"])
|
||||
@check_permission("sys:link:add")
|
||||
@check_demo
|
||||
def add():
|
||||
@@ -123,15 +126,19 @@ def add():
|
||||
Returns:
|
||||
JSON: 操作结果
|
||||
"""
|
||||
result = link.add_link()
|
||||
return result
|
||||
json_data, err = parse_request_body()
|
||||
if err:
|
||||
return R.failed(msg=err)
|
||||
link.add_link(json_data)
|
||||
return R.ok(msg="添加成功")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 友链更新
|
||||
# ============================================================
|
||||
|
||||
@link_blue.route('/update', methods=["PUT"])
|
||||
|
||||
@link_blue.route("/update", methods=["PUT"])
|
||||
@check_permission("sys:link:update")
|
||||
@check_demo
|
||||
def update():
|
||||
@@ -144,15 +151,19 @@ def update():
|
||||
Returns:
|
||||
JSON: 操作结果
|
||||
"""
|
||||
result = link.update_link()
|
||||
return result
|
||||
json_data, err = parse_request_body()
|
||||
if err:
|
||||
return R.failed(msg=err)
|
||||
link.update_link(json_data)
|
||||
return R.ok(msg="更新成功")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 友链删除
|
||||
# ============================================================
|
||||
|
||||
@link_blue.route('/delete/<string:id>', methods=["DELETE"])
|
||||
|
||||
@link_blue.route("/delete/<string:id>", methods=["DELETE"])
|
||||
@check_permission("sys:link:delete")
|
||||
@check_demo
|
||||
def delete(id):
|
||||
@@ -165,15 +176,16 @@ def delete(id):
|
||||
Returns:
|
||||
JSON: 操作结果
|
||||
"""
|
||||
result = link.delete_links(id)
|
||||
return result
|
||||
count = link.delete_links(id)
|
||||
return R.ok(msg=f"本次共删除{count}条数据")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 友链批量删除
|
||||
# ============================================================
|
||||
|
||||
@link_blue.route('/batchDelete', methods=["DELETE"])
|
||||
|
||||
@link_blue.route("/batchDelete", methods=["DELETE"])
|
||||
@check_permission("sys:link:batch_delete")
|
||||
@check_demo
|
||||
def batch_delete():
|
||||
@@ -199,7 +211,8 @@ def batch_delete():
|
||||
# 友链状态设置
|
||||
# ============================================================
|
||||
|
||||
@link_blue.route('/status', methods=["PUT"])
|
||||
|
||||
@link_blue.route("/status", methods=["PUT"])
|
||||
@check_permission("sys:link:status")
|
||||
@check_demo
|
||||
def status():
|
||||
@@ -212,5 +225,8 @@ def status():
|
||||
Returns:
|
||||
JSON: 操作结果
|
||||
"""
|
||||
result = link.update_link_status()
|
||||
return result
|
||||
json_data, err = parse_request_body()
|
||||
if err:
|
||||
return R.failed(msg=err)
|
||||
link.update_link_status(json_data)
|
||||
return R.ok(msg="更新成功")
|
||||
|
||||
+97
-152
@@ -65,19 +65,17 @@
|
||||
import logging
|
||||
|
||||
from datetime import datetime, timezone
|
||||
from flask import request
|
||||
from sqlalchemy import and_
|
||||
|
||||
from src.common.constants.common import PAGE_SIZE
|
||||
from src.common.constants.dictionary_constants import LINK_TYPE_LIST, LINK_FORM_LIST
|
||||
from src.modules.cms.link.schema import LinkForm, LinkStatusForm
|
||||
from src.modules.cms.link.models import Link
|
||||
from src.core.database import db
|
||||
from src.core import response as R
|
||||
from src.modules.cms.link.repository import LinkRepository
|
||||
from src.core.exceptions import BizError
|
||||
from src.common.utils import regular
|
||||
from src.common.utils.case_converter import convert_camel_to_snake
|
||||
from src.common.utils.model_utils import models_to_list, model_to_dict
|
||||
from src.common.utils.request import parse_request_body, parse_id_list, like_contains
|
||||
from src.common.utils.model_utils import model_to_dict
|
||||
from src.common.utils.request import parse_id_list, like_contains
|
||||
from src.common.utils.rich_text import get_file_url, save_file
|
||||
from src.core.security import get_username
|
||||
|
||||
@@ -89,7 +87,8 @@ logger = logging.getLogger(__name__)
|
||||
# 友链分页查询
|
||||
# ============================================================
|
||||
|
||||
def get_link_page():
|
||||
|
||||
def get_link_page(params: dict) -> dict:
|
||||
"""
|
||||
查询友链分页数据
|
||||
|
||||
@@ -112,31 +111,26 @@ def get_link_page():
|
||||
"pages": 总页数
|
||||
}
|
||||
"""
|
||||
try:
|
||||
# 获取分页参数
|
||||
page_no = int(request.args.get('pageNo', 1))
|
||||
page_size = int(request.args.get('pageSize', PAGE_SIZE))
|
||||
# 获取分页参数
|
||||
page_no = int(params.get("pageNo", 1))
|
||||
page_size = int(params.get("pageSize", PAGE_SIZE))
|
||||
|
||||
# 应用筛选条件
|
||||
query = _apply_filters()
|
||||
# 应用筛选条件
|
||||
query = _apply_filters(params)
|
||||
|
||||
# 记录总数
|
||||
total = query.count()
|
||||
# 计算总页数
|
||||
pages = (total + page_size - 1) // page_size if total > 0 else 0
|
||||
# 记录总数
|
||||
total = query.count()
|
||||
# 计算总页数
|
||||
pages = (total + page_size - 1) // page_size if total > 0 else 0
|
||||
|
||||
# 分页查询
|
||||
link_list = query.limit(page_size).offset((page_no - 1) * page_size).all()
|
||||
# 构建返回数据
|
||||
page_data = _build_page_data(link_list, total, page_size, page_no, pages)
|
||||
return R.ok(data=page_data)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"查询友链分页数据异常: {str(e)}")
|
||||
return R.failed(msg="查询失败,请稍后重试")
|
||||
# 分页查询
|
||||
link_list = query.limit(page_size).offset((page_no - 1) * page_size).all()
|
||||
# 构建返回数据
|
||||
page_data = _build_page_data(link_list, total, page_size, page_no, pages)
|
||||
return page_data
|
||||
|
||||
|
||||
def _apply_filters():
|
||||
def _apply_filters(params: dict):
|
||||
"""
|
||||
应用查询筛选条件
|
||||
|
||||
@@ -156,22 +150,22 @@ def _apply_filters():
|
||||
query = Link.query.filter(Link.is_delete == 0)
|
||||
|
||||
# 友链名称模糊筛选
|
||||
name = request.args.get('name')
|
||||
name = params.get("name")
|
||||
if name:
|
||||
query = query.filter(Link.name.like(like_contains(name), escape='\\'))
|
||||
query = query.filter(Link.name.like(like_contains(name), escape="\\"))
|
||||
|
||||
# 友链类型精确筛选
|
||||
link_type = request.args.get('type')
|
||||
link_type = params.get("type")
|
||||
if link_type:
|
||||
query = query.filter(Link.type == link_type)
|
||||
|
||||
# 友链形式精确筛选
|
||||
form = request.args.get('form')
|
||||
form = params.get("form")
|
||||
if form:
|
||||
query = query.filter(Link.form == form)
|
||||
|
||||
# 友链状态精确筛选
|
||||
status = request.args.get('status')
|
||||
status = params.get("status")
|
||||
if status:
|
||||
query = query.filter(Link.status == status)
|
||||
|
||||
@@ -198,27 +192,22 @@ def _build_page_data(link_list, total, page_size, page_no, pages):
|
||||
for item in link_list:
|
||||
data = model_to_dict(item)
|
||||
# 添加友链类型描述
|
||||
data['typeName'] = LINK_TYPE_LIST.get(item.type)
|
||||
data["typeName"] = LINK_TYPE_LIST.get(item.type)
|
||||
# 添加友链形式描述
|
||||
data['formName'] = LINK_FORM_LIST.get(item.form)
|
||||
data["formName"] = LINK_FORM_LIST.get(item.form)
|
||||
# 友链图片URL
|
||||
if item.image:
|
||||
data['image'] = get_file_url(item.image)
|
||||
data["image"] = get_file_url(item.image)
|
||||
records.append(data)
|
||||
|
||||
return {
|
||||
'records': records,
|
||||
'total': total,
|
||||
'size': page_size,
|
||||
'current': page_no,
|
||||
'pages': pages
|
||||
}
|
||||
return {"records": records, "total": total, "size": page_size, "current": page_no, "pages": pages}
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 友链详情查询
|
||||
# ============================================================
|
||||
|
||||
|
||||
def get_link_detail(link_id):
|
||||
"""
|
||||
根据ID查询友链详情(返回字典格式)
|
||||
@@ -241,7 +230,7 @@ def get_link_detail(link_id):
|
||||
data = model_to_dict(link)
|
||||
# 友链图片URL
|
||||
if link.image:
|
||||
data['image'] = get_file_url(link.image)
|
||||
data["image"] = get_file_url(link.image)
|
||||
return data
|
||||
|
||||
except Exception as e:
|
||||
@@ -253,6 +242,7 @@ def get_link_detail(link_id):
|
||||
# 友链信息查询(根据ID)- 核心查询方法
|
||||
# ============================================================
|
||||
|
||||
|
||||
def get_info(link_id: int):
|
||||
"""
|
||||
根据ID查询友链信息(返回模型对象)
|
||||
@@ -278,26 +268,10 @@ def get_info(link_id: int):
|
||||
if link:
|
||||
print(link.name)
|
||||
"""
|
||||
# 参数有效性验证
|
||||
if not link_id or link_id <= 0:
|
||||
return None
|
||||
|
||||
try:
|
||||
# 查询未删除的友链
|
||||
link = Link.query.filter(
|
||||
and_(Link.id == link_id, Link.is_delete == 0)
|
||||
).first()
|
||||
return link
|
||||
except Exception as e:
|
||||
logger.error(f"查询友链信息异常,ID: {link_id}, 错误: {str(e)}")
|
||||
return None
|
||||
return LinkRepository.get_by_id(link_id)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 友链添加
|
||||
# ============================================================
|
||||
|
||||
def add_link():
|
||||
def add_link(data: dict) -> None:
|
||||
"""
|
||||
添加友链
|
||||
|
||||
@@ -310,40 +284,29 @@ def add_link():
|
||||
Returns:
|
||||
R: 操作结果
|
||||
"""
|
||||
try:
|
||||
# 获取参数
|
||||
json_data, error = parse_request_body()
|
||||
if error:
|
||||
return R.failed(msg=error)
|
||||
|
||||
# 表单验证
|
||||
form = LinkForm(data=json_data)
|
||||
if not form.validate():
|
||||
err_msg = regular.get_err(form)
|
||||
return R.failed(msg=err_msg)
|
||||
# 表单验证
|
||||
form = LinkForm(data=data)
|
||||
if not form.validate():
|
||||
raise BizError(regular.get_err(form))
|
||||
|
||||
# 处理友链图片
|
||||
image = form.data.get('image')
|
||||
if image:
|
||||
form.image.data = save_file(image, "link")
|
||||
# 处理友链图片
|
||||
image = form.data.get("image")
|
||||
if image:
|
||||
form.image.data = save_file(image, "link")
|
||||
|
||||
# 创建友链
|
||||
link = Link(**form.data)
|
||||
link.create_user = get_username()
|
||||
link.save()
|
||||
|
||||
return R.ok(msg="添加成功")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"添加友链异常: {str(e)}")
|
||||
return R.failed(msg="添加失败,请稍后重试")
|
||||
# 创建友链
|
||||
link = Link(**form.data)
|
||||
link.create_user = get_username()
|
||||
link.save()
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 友链更新
|
||||
# ============================================================
|
||||
|
||||
def update_link():
|
||||
|
||||
def update_link(data: dict) -> None:
|
||||
"""
|
||||
更新友链
|
||||
|
||||
@@ -357,57 +320,47 @@ def update_link():
|
||||
Returns:
|
||||
R: 操作结果
|
||||
"""
|
||||
try:
|
||||
# 获取参数
|
||||
json_data, error = parse_request_body()
|
||||
if error:
|
||||
return R.failed(msg=error)
|
||||
|
||||
# 表单验证
|
||||
form = LinkForm(data=json_data)
|
||||
if not form.validate():
|
||||
return R.failed(msg=regular.get_err(form))
|
||||
# 表单验证
|
||||
form = LinkForm(data=data)
|
||||
if not form.validate():
|
||||
raise BizError(regular.get_err(form))
|
||||
|
||||
# 获取友链ID
|
||||
link_id = form.data.get('id')
|
||||
if not link_id or int(link_id) <= 0:
|
||||
return R.failed("友链ID无效")
|
||||
link_id = int(link_id)
|
||||
# 获取友链ID
|
||||
link_id = form.data.get("id")
|
||||
if not link_id or int(link_id) <= 0:
|
||||
raise BizError("友链ID无效")
|
||||
link_id = int(link_id)
|
||||
|
||||
# 复用 get_info 方法验证友链是否存在
|
||||
link = get_info(link_id)
|
||||
if not link:
|
||||
return R.failed("友链不存在")
|
||||
# 复用 get_info 方法验证友链是否存在
|
||||
link = get_info(link_id)
|
||||
if not link:
|
||||
raise BizError("友链不存在")
|
||||
|
||||
# 处理友链图片
|
||||
image = form.data.get('image')
|
||||
if image:
|
||||
form.image.data = save_file(image, "link")
|
||||
# 处理友链图片
|
||||
image = form.data.get("image")
|
||||
if image:
|
||||
form.image.data = save_file(image, "link")
|
||||
|
||||
# 更新友链信息(移除ID,避免更新主键)
|
||||
form_data = convert_camel_to_snake(form.data.copy())
|
||||
form_data.pop('id', None)
|
||||
# 更新友链信息(移除ID,避免更新主键)
|
||||
form_data = convert_camel_to_snake(form.data.copy())
|
||||
form_data.pop("id", None)
|
||||
|
||||
form_data['update_time'] = datetime.now(tz=timezone.utc)
|
||||
form_data['update_user'] = get_username()
|
||||
form_data["update_time"] = datetime.now(tz=timezone.utc)
|
||||
form_data["update_user"] = get_username()
|
||||
|
||||
result = Link.query.filter_by(id=link_id).update(form_data)
|
||||
result = Link.query.filter_by(id=link_id).update(form_data)
|
||||
|
||||
if not result:
|
||||
return R.failed("更新失败")
|
||||
|
||||
return R.ok(msg="更新成功")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"更新友链异常: {str(e)}")
|
||||
return R.failed(msg="更新友链失败,请稍后重试")
|
||||
if not result:
|
||||
raise BizError("更新失败")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 友链删除
|
||||
# ============================================================
|
||||
|
||||
def delete_links(link_ids):
|
||||
|
||||
def delete_links(link_ids: str) -> int:
|
||||
"""
|
||||
删除友链(批量删除)
|
||||
|
||||
@@ -420,14 +373,18 @@ def delete_links(link_ids):
|
||||
Returns:
|
||||
R: 操作结果
|
||||
"""
|
||||
return Link.batch_delete_r(link_ids)
|
||||
link_ids_list = parse_id_list(link_ids)
|
||||
if not link_ids_list:
|
||||
raise BizError("无效的记录ID")
|
||||
return Link.batch_delete(link_ids_list)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 友链状态设置
|
||||
# ============================================================
|
||||
|
||||
def update_link_status():
|
||||
|
||||
def update_link_status(data: dict) -> None:
|
||||
"""
|
||||
设置友链状态
|
||||
|
||||
@@ -436,35 +393,23 @@ def update_link_status():
|
||||
Returns:
|
||||
R: 操作结果
|
||||
"""
|
||||
try:
|
||||
# 获取参数
|
||||
json_data, error = parse_request_body()
|
||||
if error:
|
||||
return R.failed(msg=error)
|
||||
|
||||
# 表单验证
|
||||
form = LinkStatusForm(data=json_data)
|
||||
if not form.validate():
|
||||
err_msg = regular.get_err(form)
|
||||
return R.failed(msg=err_msg)
|
||||
# 表单验证
|
||||
form = LinkStatusForm(data=data)
|
||||
if not form.validate():
|
||||
raise BizError(regular.get_err(form))
|
||||
|
||||
link_id = int(form.data['id'])
|
||||
status = int(form.data['status'])
|
||||
link_id = int(form.data["id"])
|
||||
status = int(form.data["status"])
|
||||
|
||||
# 复用 get_info 方法验证友链是否存在
|
||||
link = get_info(link_id)
|
||||
if not link:
|
||||
return R.failed("友链不存在")
|
||||
# 复用 get_info 方法验证友链是否存在
|
||||
link = get_info(link_id)
|
||||
if not link:
|
||||
raise BizError("友链不存在")
|
||||
|
||||
# 更新状态
|
||||
update_data = {"status": status, "update_time": datetime.now(tz=timezone.utc), "update_user": get_username()}
|
||||
result = Link.query.filter_by(id=link_id).update(update_data)
|
||||
# 更新状态
|
||||
update_data = {"status": status, "update_time": datetime.now(tz=timezone.utc), "update_user": get_username()}
|
||||
result = Link.query.filter_by(id=link_id).update(update_data)
|
||||
|
||||
if not result:
|
||||
return R.failed("设置失败")
|
||||
|
||||
return R.ok(msg="设置成功")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"设置友链状态异常: {str(e)}")
|
||||
return R.failed(msg="设置友链状态失败,请稍后重试")
|
||||
if not result:
|
||||
raise BizError("设置失败")
|
||||
|
||||
Reference in New Issue
Block a user