refactor: P4c 批次3 服务层改造(dept/city tree 型模块)

- add/update/delete/get_info 按 codemod 改造(get_info 委托 Repository)
- get_dept_list/get_city_list 手动 params 化返回 list
- city 删除函数 f-string R.failed → raise BizError
- router 取参包 R;新增 dept/city repository.py

【验收】flake8 零告警;应用启动;dept/city 服务运行时正常;12 passed

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
DjangoAdmin Dev
2026-08-07 15:32:46 +08:00
co-authored by Claude
parent c2a4910d60
commit d97e456744
8 changed files with 229 additions and 256 deletions
-1
View File
@@ -50,7 +50,6 @@ from src.common.base_db import BaseDB
from src.common.base_model import BaseModel from src.common.base_model import BaseModel
from config import DB_PREFIX from config import DB_PREFIX
from src.core.database import db from src.core.database import db
from src.common.utils.case_converter import convert_camel_to_snake
# ============================================================ # ============================================================
+15
View File
@@ -0,0 +1,15 @@
"""
City 仓储模块
=============================================================
数据访问层,继承 BaseRepository 获得通用 CRUD 能力。
"""
from src.common.base_repository import BaseRepository
from src.modules.city.models import City
class CityRepository(BaseRepository):
"""City 仓储"""
model = City
+29 -16
View File
@@ -55,21 +55,24 @@
application.middleware.check_permission - 权限校验中间件 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_demo import check_demo
from application.middleware.check_permission import check_permission from application.middleware.check_permission import check_permission
from src.modules.city import service as city from src.modules.city import service as city
city_blue = Blueprint('city', __name__, url_prefix='/city') from src.common.utils.request import parse_request_body
from src.core import response as R from src.core import response as R
city_blue = Blueprint("city", __name__, url_prefix="/city")
# ============================================================ # ============================================================
# 城市分页查询 # 城市分页查询
# ============================================================ # ============================================================
@city_blue.route('/page', methods=["GET"])
@city_blue.route("/page", methods=["GET"])
@check_permission("sys:city:page") @check_permission("sys:city:page")
def page(): def page():
""" """
@@ -81,15 +84,15 @@ def page():
Returns: Returns:
JSON: 城市分页数据,包含 records(数据列表)、total(总记录数)等 JSON: 城市分页数据,包含 records(数据列表)、total(总记录数)等
""" """
result = city.get_city_list() return R.ok(data=city.get_city_list(request.args))
return result
# ============================================================ # ============================================================
# 城市详情查询 # 城市详情查询
# ============================================================ # ============================================================
@city_blue.route('/detail/<int:id>', methods=["GET"])
@city_blue.route("/detail/<int:id>", methods=["GET"])
@check_permission("sys:city:detail") @check_permission("sys:city:detail")
def detail(id): def detail(id):
""" """
@@ -109,7 +112,8 @@ def detail(id):
# 城市添加 # 城市添加
# ============================================================ # ============================================================
@city_blue.route('/add', methods=["POST"])
@city_blue.route("/add", methods=["POST"])
@check_permission("sys:city:add") @check_permission("sys:city:add")
@check_demo @check_demo
def add(): def add():
@@ -122,15 +126,19 @@ def add():
Returns: Returns:
JSON: 操作结果 JSON: 操作结果
""" """
result = city.add_city() json_data, err = parse_request_body()
return result if err:
return R.failed(msg=err)
city.add_city(json_data)
return R.ok(msg="添加成功")
# ============================================================ # ============================================================
# 城市更新 # 城市更新
# ============================================================ # ============================================================
@city_blue.route('/update', methods=["PUT"])
@city_blue.route("/update", methods=["PUT"])
@check_permission("sys:city:update") @check_permission("sys:city:update")
@check_demo @check_demo
def update(): def update():
@@ -143,15 +151,19 @@ def update():
Returns: Returns:
JSON: 操作结果 JSON: 操作结果
""" """
result = city.update_city() json_data, err = parse_request_body()
return result if err:
return R.failed(msg=err)
city.update_city(json_data)
return R.ok(msg="更新成功")
# ============================================================ # ============================================================
# 城市删除 # 城市删除
# ============================================================ # ============================================================
@city_blue.route('/delete/<string:id>', methods=["DELETE"])
@city_blue.route("/delete/<string:id>", methods=["DELETE"])
@check_permission("sys:city:delete") @check_permission("sys:city:delete")
@check_demo @check_demo
def delete(id): def delete(id):
@@ -164,15 +176,16 @@ def delete(id):
Returns: Returns:
JSON: 操作结果 JSON: 操作结果
""" """
result = city.delete_cities(id) count = city.delete_cities(id)
return result return R.ok(msg=f"本次共删除{count}条数据")
# ============================================================ # ============================================================
# 子级城市查询 # 子级城市查询
# ============================================================ # ============================================================
@city_blue.route('/getCityList/<string:city_code>', methods=["GET"])
@city_blue.route("/getCityList/<string:city_code>", methods=["GET"])
def get_child_list(city_code): def get_child_list(city_code):
""" """
根据城市编码查询子级城市 根据城市编码查询子级城市
+56 -95
View File
@@ -65,17 +65,16 @@
import logging import logging
from datetime import datetime, timezone from datetime import datetime, timezone
from flask import request
from sqlalchemy import and_ from sqlalchemy import and_
from src.common.constants.dictionary_constants import CITY_LEVEL_LIST from src.common.constants.dictionary_constants import CITY_LEVEL_LIST
from src.modules.city.schema import CityForm from src.modules.city.schema import CityForm
from src.modules.city.models import City from src.modules.city.models import City
from src.core.database import db from src.modules.city.repository import CityRepository
from src.core import response as R from src.core.exceptions import BizError
from src.common.utils import regular from src.common.utils import regular
from src.common.utils.case_converter import convert_camel_to_snake from src.common.utils.case_converter import convert_camel_to_snake
from src.common.utils.request import parse_request_body, parse_id_list, like_contains from src.common.utils.request import parse_id_list, like_contains
from src.common.utils.model_utils import models_to_list, model_to_dict from src.common.utils.model_utils import models_to_list, model_to_dict
from src.core.security import get_username from src.core.security import get_username
@@ -87,38 +86,32 @@ logger = logging.getLogger(__name__)
# 城市列表查询 # 城市列表查询
# ============================================================ # ============================================================
def get_city_list():
def get_city_list(params: dict) -> list:
""" """
查询城市列表 查询城市列表
用于城市管理页面的列表展示,支持按父级ID和名称筛选。 用于城市管理页面的列表展示,支持按父级ID和名称筛选。
Args: Args:
request: Flask request对象,包含查询参数 params: 查询参数
- pid: 父级ID(可选,默认为0,查询顶级城市) - pid: 父级ID(可选,默认为0,查询顶级城市)
- name: 城市名称(可选,模糊查询) - name: 城市名称(可选,模糊查询)
Returns: Returns:
R: 包含城市列表的JSON响应 list: 城市字典列表
""" """
try:
# 应用筛选条件 # 应用筛选条件
query = _apply_filters() query = _apply_filters(params)
# 查询数据 # 查询数据
city_list = query.all() city_list = query.all()
# 转换为字典列表并补充关联数据 # 转换为字典列表并补充关联数据
records = _enrich_city_records(city_list) return _enrich_city_records(city_list)
return R.ok(data=records)
except Exception as e:
logger.error(f"查询城市列表异常: {str(e)}")
return R.failed(msg="查询失败,请稍后重试")
def _apply_filters(): def _apply_filters(params: dict):
""" """
应用查询筛选条件 应用查询筛选条件
@@ -134,7 +127,7 @@ def _apply_filters():
query = City.query.filter(City.is_delete == 0) query = City.query.filter(City.is_delete == 0)
# 父级ID精确筛选(默认为0,查询顶级城市) # 父级ID精确筛选(默认为0,查询顶级城市)
pid = request.args.get('pid', 0) pid = params.get("pid", 0)
if pid is not None: if pid is not None:
try: try:
query = query.filter(City.pid == int(pid)) query = query.filter(City.pid == int(pid))
@@ -142,9 +135,9 @@ def _apply_filters():
pass pass
# 城市名称模糊筛选 # 城市名称模糊筛选
name = request.args.get('name') name = params.get("name")
if name: if name:
query = query.filter(City.name.like(like_contains(name), escape='\\')) query = query.filter(City.name.like(like_contains(name), escape="\\"))
# 按ID升序排列 # 按ID升序排列
return query.order_by(City.id.asc()) return query.order_by(City.id.asc())
@@ -167,10 +160,10 @@ def _enrich_city_records(city_list):
for data in records: for data in records:
# 城市级别名称 # 城市级别名称
level = data.get('level') level = data.get("level")
data['level_name'] = CITY_LEVEL_LIST.get(level) if level else None data["level_name"] = CITY_LEVEL_LIST.get(level) if level else None
# 是否有子级(level < 3 表示还有下级) # 是否有子级(level < 3 表示还有下级)
data['have_child'] = data.get('level', 4) < 3 if data.get('level') else False data["have_child"] = data.get("level", 4) < 3 if data.get("level") else False
return records return records
@@ -179,6 +172,7 @@ def _enrich_city_records(city_list):
# 城市详情查询 # 城市详情查询
# ============================================================ # ============================================================
def get_city_detail(city_id): def get_city_detail(city_id):
""" """
根据ID查询城市详情(返回字典格式) 根据ID查询城市详情(返回字典格式)
@@ -209,6 +203,7 @@ def get_city_detail(city_id):
# 城市信息查询(根据ID)- 核心查询方法 # 城市信息查询(根据ID)- 核心查询方法
# ============================================================ # ============================================================
def get_info(city_id: int): def get_info(city_id: int):
""" """
根据ID查询城市信息(返回模型对象) 根据ID查询城市信息(返回模型对象)
@@ -234,26 +229,10 @@ def get_info(city_id: int):
if city: if city:
print(city.name) print(city.name)
""" """
# 参数有效性验证 return CityRepository.get_by_id(city_id)
if not city_id or city_id <= 0:
return None
try:
# 查询未删除的城市
city = City.query.filter(
and_(City.id == city_id, City.is_delete == 0)
).first()
return city
except Exception as e:
logger.error(f"查询城市信息异常,ID: {city_id}, 错误: {str(e)}")
return None
# ============================================================ def add_city(data: dict) -> None:
# 城市添加
# ============================================================
def add_city():
""" """
添加城市 添加城市
@@ -265,35 +244,24 @@ def add_city():
Returns: Returns:
R: 操作结果 R: 操作结果
""" """
try:
# 获取参数
json_data, error = parse_request_body()
if error:
return R.failed(msg=error)
# 表单验证 # 表单验证
form = CityForm(data=json_data) form = CityForm(data=data)
if not form.validate(): if not form.validate():
err_msg = regular.get_err(form) raise BizError(regular.get_err(form))
return R.failed(msg=err_msg)
# 创建城市 # 创建城市
city = City(**form.data) city = City(**form.data)
city.create_user = get_username() city.create_user = get_username()
city.save() city.save()
return R.ok(msg="添加成功")
except Exception as e:
logger.error(f"添加城市异常: {str(e)}")
return R.failed(msg="添加城市失败,请稍后重试")
# ============================================================ # ============================================================
# 城市更新 # 城市更新
# ============================================================ # ============================================================
def update_city():
def update_city(data: dict) -> None:
""" """
更新城市 更新城市
@@ -306,52 +274,42 @@ def update_city():
Returns: Returns:
R: 操作结果 R: 操作结果
""" """
try:
# 获取参数
json_data, error = parse_request_body()
if error:
return R.failed(msg=error)
# 表单验证 # 表单验证
form = CityForm(data=json_data) form = CityForm(data=data)
if not form.validate(): if not form.validate():
return R.failed(msg=regular.get_err(form)) raise BizError(regular.get_err(form))
# 获取城市ID # 获取城市ID
city_id = form.data.get('id') city_id = form.data.get("id")
if not city_id or int(city_id) <= 0: if not city_id or int(city_id) <= 0:
return R.failed("城市ID无效") raise BizError("城市ID无效")
city_id = int(city_id) city_id = int(city_id)
# 复用 get_info 方法验证城市是否存在 # 复用 get_info 方法验证城市是否存在
city = get_info(city_id) city = get_info(city_id)
if not city: if not city:
return R.failed("城市不存在") raise BizError("城市不存在")
# 更新城市信息(移除ID,避免更新主键) # 更新城市信息(移除ID,避免更新主键)
form_data = convert_camel_to_snake(form.data.copy()) form_data = convert_camel_to_snake(form.data.copy())
form_data.pop('id', None) form_data.pop("id", None)
form_data['update_time'] = datetime.now(tz=timezone.utc) form_data["update_time"] = datetime.now(tz=timezone.utc)
form_data['update_user'] = get_username() form_data["update_user"] = get_username()
result = City.query.filter_by(id=city_id).update(form_data) result = City.query.filter_by(id=city_id).update(form_data)
if not result: if not result:
return R.failed("更新失败") raise BizError("更新失败")
return R.ok(msg="更新成功")
except Exception as e:
logger.error(f"更新城市异常: {str(e)}")
return R.failed(msg="更新城市失败,请稍后重试")
# ============================================================ # ============================================================
# 城市删除 # 城市删除
# ============================================================ # ============================================================
def delete_cities(city_ids):
def delete_cities(city_ids: str) -> int:
""" """
删除城市(批量删除) 删除城市(批量删除)
@@ -365,28 +323,30 @@ def delete_cities(city_ids):
R: 操作结果 R: 操作结果
""" """
if not city_ids: if not city_ids:
return R.failed("记录ID不存在") raise BizError("记录ID不存在")
# 解析ID列表 # 解析ID列表
id_list = parse_id_list(city_ids) id_list = parse_id_list(city_ids)
if not id_list: if not id_list:
return R.failed("无效的记录ID") raise BizError("无效的记录ID")
# 检查是否有子级城市 # 检查是否有子级城市
for city_id in id_list: for city_id in id_list:
child_count = City.query.filter( child_count = City.query.filter(and_(City.pid == city_id, City.is_delete == 0)).count()
and_(City.pid == city_id, City.is_delete == 0)
).count()
if child_count > 0: if child_count > 0:
return R.failed(f"城市ID {city_id} 存在子级城市,请先删除子级城市") raise BizError(f"城市ID {city_id} 存在子级城市,请先删除子级城市")
return City.batch_delete_r(city_ids) city_ids_list = parse_id_list(city_ids)
if not city_ids_list:
raise BizError("无效的记录ID")
return City.batch_delete(city_ids_list)
# ============================================================ # ============================================================
# 子级城市查询 # 子级城市查询
# ============================================================ # ============================================================
def get_child_cities(city_code): def get_child_cities(city_code):
""" """
根据城市编码获取子级城市列表 根据城市编码获取子级城市列表
@@ -408,9 +368,9 @@ def get_child_cities(city_code):
try: try:
# 查询子级城市 # 查询子级城市
child_list = City.query.filter( child_list = (
and_(City.parent_code == city_code, City.is_delete == 0) City.query.filter(and_(City.parent_code == city_code, City.is_delete == 0)).order_by(City.id.asc()).all()
).order_by(City.id.asc()).all() )
# 构建返回数据 # 构建返回数据
result = models_to_list(child_list) result = models_to_list(child_list)
@@ -425,6 +385,7 @@ def get_child_cities(city_code):
# 城市树形数据获取 # 城市树形数据获取
# ============================================================ # ============================================================
def get_city_tree(): def get_city_tree():
""" """
获取城市树形数据 获取城市树形数据
@@ -468,16 +429,16 @@ def _build_city_tree(city_list, parent_id=0):
""" """
tree = [] tree = []
for city in city_list: for city in city_list:
if city.get('pid') == parent_id: if city.get("pid") == parent_id:
node = { node = {
'id': city.get('id'), "id": city.get("id"),
'name': city.get('name'), "name": city.get("name"),
'code': city.get('area_code'), "code": city.get("area_code"),
'level': city.get('level'), "level": city.get("level"),
'children': _build_city_tree(city_list, city.get('id')) "children": _build_city_tree(city_list, city.get("id")),
} }
# 如果没有子节点,移除children字段 # 如果没有子节点,移除children字段
if not node['children']: if not node["children"]:
del node['children'] del node["children"]
tree.append(node) tree.append(node)
return tree return tree
-1
View File
@@ -50,7 +50,6 @@ from src.common.base_db import BaseDB
from src.common.base_model import BaseModel from src.common.base_model import BaseModel
from config import DB_PREFIX from config import DB_PREFIX
from src.core.database import db from src.core.database import db
from src.common.utils.case_converter import convert_camel_to_snake
# ============================================================ # ============================================================
+15
View File
@@ -0,0 +1,15 @@
"""
Dept 仓储模块
=============================================================
数据访问层,继承 BaseRepository 获得通用 CRUD 能力。
"""
from src.common.base_repository import BaseRepository
from src.modules.system.dept.models import Dept
class DeptRepository(BaseRepository):
"""Dept 仓储"""
model = Dept
+29 -16
View File
@@ -55,21 +55,24 @@
application.middleware.check_permission - 权限校验中间件 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_demo import check_demo
from application.middleware.check_permission import check_permission from application.middleware.check_permission import check_permission
from src.modules.system.dept import service as dept from src.modules.system.dept import service as dept
dept_blue = Blueprint('dept', __name__, url_prefix='/dept') from src.common.utils.request import parse_request_body
from src.core import response as R from src.core import response as R
dept_blue = Blueprint("dept", __name__, url_prefix="/dept")
# ============================================================ # ============================================================
# 部门列表查询 # 部门列表查询
# ============================================================ # ============================================================
@dept_blue.route('/list', methods=["GET"])
@dept_blue.route("/list", methods=["GET"])
@check_permission("sys:dept:list") @check_permission("sys:dept:list")
def list(): def list():
""" """
@@ -81,15 +84,15 @@ def list():
Returns: Returns:
JSON: 部门列表数据 JSON: 部门列表数据
""" """
result = dept.get_dept_list() return R.ok(data=dept.get_dept_list(request.args))
return result
# ============================================================ # ============================================================
# 部门详情查询 # 部门详情查询
# ============================================================ # ============================================================
@dept_blue.route('/detail/<int:id>', methods=["GET"])
@dept_blue.route("/detail/<int:id>", methods=["GET"])
@check_permission("sys:dept:detail") @check_permission("sys:dept:detail")
def detail(id): def detail(id):
""" """
@@ -109,7 +112,8 @@ def detail(id):
# 部门添加 # 部门添加
# ============================================================ # ============================================================
@dept_blue.route('/add', methods=["POST"])
@dept_blue.route("/add", methods=["POST"])
@check_permission("sys:dept:add") @check_permission("sys:dept:add")
@check_demo @check_demo
def add(): def add():
@@ -122,15 +126,19 @@ def add():
Returns: Returns:
JSON: 操作结果 JSON: 操作结果
""" """
result = dept.add_dept() json_data, err = parse_request_body()
return result if err:
return R.failed(msg=err)
dept.add_dept(json_data)
return R.ok(msg="添加成功")
# ============================================================ # ============================================================
# 部门更新 # 部门更新
# ============================================================ # ============================================================
@dept_blue.route('/update', methods=["PUT"])
@dept_blue.route("/update", methods=["PUT"])
@check_permission("sys:dept:update") @check_permission("sys:dept:update")
@check_demo @check_demo
def update(): def update():
@@ -143,15 +151,19 @@ def update():
Returns: Returns:
JSON: 操作结果 JSON: 操作结果
""" """
result = dept.update_dept() json_data, err = parse_request_body()
return result if err:
return R.failed(msg=err)
dept.update_dept(json_data)
return R.ok(msg="更新成功")
# ============================================================ # ============================================================
# 部门删除 # 部门删除
# ============================================================ # ============================================================
@dept_blue.route('/delete/<string:id>', methods=["DELETE"])
@dept_blue.route("/delete/<string:id>", methods=["DELETE"])
@check_permission("sys:dept:delete") @check_permission("sys:dept:delete")
@check_demo @check_demo
def delete(id): def delete(id):
@@ -164,15 +176,16 @@ def delete(id):
Returns: Returns:
JSON: 操作结果 JSON: 操作结果
""" """
result = dept.delete_depts(id) count = dept.delete_depts(id)
return result return R.ok(msg=f"本次共删除{count}条数据")
# ============================================================ # ============================================================
# 部门数据列表获取 # 部门数据列表获取
# ============================================================ # ============================================================
@dept_blue.route('/getDeptList', methods=["GET"])
@dept_blue.route("/getDeptList", methods=["GET"])
def get_dept_list(): def get_dept_list():
""" """
获取部门数据列表 获取部门数据列表
+41 -83
View File
@@ -64,16 +64,15 @@
import logging import logging
from datetime import datetime, timezone from datetime import datetime, timezone
from flask import request
from sqlalchemy import and_ from sqlalchemy import and_
from src.modules.system.dept.schema import DeptForm from src.modules.system.dept.schema import DeptForm
from src.modules.system.dept.models import Dept from src.modules.system.dept.models import Dept
from src.core.database import db from src.modules.system.dept.repository import DeptRepository
from src.core import response as R from src.core.exceptions import BizError
from src.common.utils import regular from src.common.utils import regular
from src.common.utils.case_converter import convert_camel_to_snake from src.common.utils.case_converter import convert_camel_to_snake
from src.common.utils.request import parse_request_body, parse_id_list, like_contains from src.common.utils.request import parse_id_list, like_contains
from src.common.utils.model_utils import models_to_list, model_to_dict from src.common.utils.model_utils import models_to_list, model_to_dict
from src.core.security import get_username from src.core.security import get_username
@@ -85,37 +84,31 @@ logger = logging.getLogger(__name__)
# 部门列表查询 # 部门列表查询
# ============================================================ # ============================================================
def get_dept_list():
def get_dept_list(params: dict) -> list:
""" """
查询部门列表(无分页) 查询部门列表(无分页)
用于部门管理页面的列表展示,支持按名称模糊搜索。 用于部门管理页面的列表展示,支持按名称模糊搜索。
Args: Args:
request: Flask request对象,包含查询参数 params: 查询参数
- name: 部门名称(可选,模糊查询) - name: 部门名称(可选,模糊查询)
Returns: Returns:
R: 包含部门列表的JSON响应 list: 部门字典列表
""" """
try:
# 应用筛选条件 # 应用筛选条件
query = _apply_filters() query = _apply_filters(params)
# 查询数据 # 查询数据
dept_list = query.all() dept_list = query.all()
# 转换为字典列表 # 转换为字典列表
records = models_to_list(dept_list) return models_to_list(dept_list)
return R.ok(data=records)
except Exception as e:
logger.error(f"查询部门列表异常: {str(e)}")
return R.failed(msg="查询失败,请稍后重试")
def _apply_filters(): def _apply_filters(params: dict):
""" """
应用查询筛选条件 应用查询筛选条件
@@ -130,9 +123,9 @@ def _apply_filters():
query = Dept.query.filter(Dept.is_delete == 0) query = Dept.query.filter(Dept.is_delete == 0)
# 部门名称模糊筛选 # 部门名称模糊筛选
name = request.args.get('name') name = params.get("name")
if name: if name:
query = query.filter(Dept.name.like(like_contains(name), escape='\\')) query = query.filter(Dept.name.like(like_contains(name), escape="\\"))
# 按排序值升序排列 # 按排序值升序排列
return query.order_by(Dept.sort.asc()) return query.order_by(Dept.sort.asc())
@@ -142,6 +135,7 @@ def _apply_filters():
# 部门详情查询 # 部门详情查询
# ============================================================ # ============================================================
def get_dept_detail(dept_id): def get_dept_detail(dept_id):
""" """
根据ID查询部门详情(返回字典格式) 根据ID查询部门详情(返回字典格式)
@@ -172,6 +166,7 @@ def get_dept_detail(dept_id):
# 部门信息查询(根据ID)- 核心查询方法 # 部门信息查询(根据ID)- 核心查询方法
# ============================================================ # ============================================================
def get_info(dept_id: int): def get_info(dept_id: int):
""" """
根据ID查询部门信息(返回模型对象) 根据ID查询部门信息(返回模型对象)
@@ -197,26 +192,10 @@ def get_info(dept_id: int):
if dept: if dept:
print(dept.name) print(dept.name)
""" """
# 参数有效性验证 return DeptRepository.get_by_id(dept_id)
if not dept_id or dept_id <= 0:
return None
try:
# 查询未删除的部门
dept = Dept.query.filter(
and_(Dept.id == dept_id, Dept.is_delete == 0)
).first()
return dept
except Exception as e:
logger.error(f"查询部门信息异常,ID: {dept_id}, 错误: {str(e)}")
return None
# ============================================================ def add_dept(data: dict) -> None:
# 部门添加
# ============================================================
def add_dept():
""" """
添加部门 添加部门
@@ -228,35 +207,24 @@ def add_dept():
Returns: Returns:
R: 操作结果 R: 操作结果
""" """
try:
# 获取参数
json_data, error = parse_request_body()
if error:
return R.failed(msg=error)
# 表单验证 # 表单验证
form = DeptForm(data=json_data) form = DeptForm(data=data)
if not form.validate(): if not form.validate():
err_msg = regular.get_err(form) raise BizError(regular.get_err(form))
return R.failed(msg=err_msg)
# 创建部门 # 创建部门
dept = Dept(**form.data) dept = Dept(**form.data)
dept.create_user = get_username() dept.create_user = get_username()
dept.save() dept.save()
return R.ok(msg="添加成功")
except Exception as e:
logger.error(f"添加部门异常: {str(e)}")
return R.failed(msg="添加部门失败,请稍后重试")
# ============================================================ # ============================================================
# 部门更新 # 部门更新
# ============================================================ # ============================================================
def update_dept():
def update_dept(data: dict) -> None:
""" """
更新部门 更新部门
@@ -269,52 +237,42 @@ def update_dept():
Returns: Returns:
R: 操作结果 R: 操作结果
""" """
try:
# 获取参数
json_data, error = parse_request_body()
if error:
return R.failed(msg=error)
# 表单验证 # 表单验证
form = DeptForm(data=json_data) form = DeptForm(data=data)
if not form.validate(): if not form.validate():
return R.failed(msg=regular.get_err(form)) raise BizError(regular.get_err(form))
# 获取部门ID # 获取部门ID
dept_id = form.data.get('id') dept_id = form.data.get("id")
if not dept_id or int(dept_id) <= 0: if not dept_id or int(dept_id) <= 0:
return R.failed("部门ID无效") raise BizError("部门ID无效")
dept_id = int(dept_id) dept_id = int(dept_id)
# 复用 get_info 方法验证部门是否存在 # 复用 get_info 方法验证部门是否存在
dept = get_info(dept_id) dept = get_info(dept_id)
if not dept: if not dept:
return R.failed("部门不存在") raise BizError("部门不存在")
# 更新部门信息(移除ID,避免更新主键) # 更新部门信息(移除ID,避免更新主键)
form_data = convert_camel_to_snake(form.data.copy()) form_data = convert_camel_to_snake(form.data.copy())
form_data.pop('id', None) form_data.pop("id", None)
form_data['update_time'] = datetime.now(tz=timezone.utc) form_data["update_time"] = datetime.now(tz=timezone.utc)
form_data['update_user'] = get_username() form_data["update_user"] = get_username()
result = Dept.query.filter_by(id=dept_id).update(form_data) result = Dept.query.filter_by(id=dept_id).update(form_data)
if not result: if not result:
return R.failed("更新失败") raise BizError("更新失败")
return R.ok(msg="更新成功")
except Exception as e:
logger.error(f"更新部门异常: {str(e)}")
return R.failed(msg="更新部门失败,请稍后重试")
# ============================================================ # ============================================================
# 部门删除 # 部门删除
# ============================================================ # ============================================================
def delete_depts(dept_ids):
def delete_depts(dept_ids: str) -> int:
""" """
删除部门(批量删除) 删除部门(批量删除)
@@ -328,28 +286,30 @@ def delete_depts(dept_ids):
R: 操作结果 R: 操作结果
""" """
if not dept_ids: if not dept_ids:
return R.failed("记录ID不存在") raise BizError("记录ID不存在")
# 解析ID列表 # 解析ID列表
id_list = parse_id_list(dept_ids) id_list = parse_id_list(dept_ids)
if not id_list: if not id_list:
return R.failed("无效的记录ID") raise BizError("无效的记录ID")
# 检查是否有子部门 # 检查是否有子部门
for dept_id in id_list: for dept_id in id_list:
child_count = Dept.query.filter( child_count = Dept.query.filter(and_(Dept.parent_id == dept_id, Dept.is_delete == 0)).count()
and_(Dept.parent_id == dept_id, Dept.is_delete == 0)
).count()
if child_count > 0: if child_count > 0:
return R.failed("存在子部门,请先删除子部门") raise BizError("存在子部门,请先删除子部门")
return Dept.batch_delete_r(dept_ids) dept_ids_list = parse_id_list(dept_ids)
if not dept_ids_list:
raise BizError("无效的记录ID")
return Dept.batch_delete(dept_ids_list)
# ============================================================ # ============================================================
# 部门树形数据获取 # 部门树形数据获取
# ============================================================ # ============================================================
def get_dept_data(): def get_dept_data():
""" """
获取部门树形数据(无分页) 获取部门树形数据(无分页)
@@ -362,9 +322,7 @@ def get_dept_data():
""" """
try: try:
# 查询所有未删除的部门 # 查询所有未删除的部门
dept_list = Dept.query.filter( dept_list = Dept.query.filter(and_(Dept.is_delete == 0, Dept.status == 1)).order_by(Dept.sort.asc()).all()
and_(Dept.is_delete == 0, Dept.status == 1)
).order_by(Dept.sort.asc()).all()
# 转换为字典列表 # 转换为字典列表
result = models_to_list(dept_list) result = models_to_list(dept_list)