refactor: P4c 最终批次-3 configuration 模块(config+config_item 合并服务)

【修复合并遗留】重名函数重命名(_apply_config_item_filters/
get_config_item_info/_build_config_item_page_data)、router 双 blueprint 合并、
中部 import 块清理、CONFIG_ITEM_TYPE_LIST 并入顶部
【特殊函数】save_config_data(data) 改入参去 R;get_config_data 返回 list
【教训】regex .*?配置项 跨 docstring 误删顶部导入(同 dictionary models),
已恢复并改精确行级处理
【验收】flake8 零告警;应用启动;config/config_item 运行时正常;12 passed

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
DjangoAdmin Dev
2026-08-07 16:41:24 +08:00
co-authored by Claude
parent 9acbf6275e
commit 0e0179859f
6 changed files with 359 additions and 524 deletions
@@ -0,0 +1,15 @@
"""
ConfigItem 仓储模块
=============================================================
数据访问层,继承 BaseRepository 获得通用 CRUD 能力。
"""
from src.common.base_repository import BaseRepository
from src.modules.configuration.models import ConfigItem
class ConfigItemRepository(BaseRepository):
"""ConfigItem 仓储"""
model = ConfigItem
@@ -0,0 +1,15 @@
"""
Config 仓储模块
=============================================================
数据访问层,继承 BaseRepository 获得通用 CRUD 能力。
"""
from src.common.base_repository import BaseRepository
from src.modules.configuration.models import Config
class ConfigRepository(BaseRepository):
"""Config 仓储"""
model = Config
+16 -78
View File
@@ -50,13 +50,13 @@ 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
# ============================================================
# 配置模型
# ============================================================
class Config(BaseModel, BaseDB):
"""
配置分组模型
@@ -84,32 +84,16 @@ class Config(BaseModel, BaseDB):
# ============================================================
# 配置名称
name = db.Column(
db.String(100),
nullable=False,
comment="配置名称"
)
name = db.Column(db.String(100), nullable=False, comment="配置名称")
# 配置编码
code = db.Column(
db.String(100),
nullable=False,
comment="配置编码"
)
code = db.Column(db.String(100), nullable=False, comment="配置编码")
# 配置排序
sort = db.Column(
db.Integer,
default=0,
comment="配置排序"
)
sort = db.Column(db.Integer, default=0, comment="配置排序")
# 配置备注
note = db.Column(
db.String(255),
nullable=True,
comment="配置备注"
)
note = db.Column(db.String(255), nullable=True, comment="配置备注")
# ============================================================
# 魔法方法
@@ -125,7 +109,6 @@ class Config(BaseModel, BaseDB):
return "配置{}".format(self.id)
"""
模型模块
=============================================================
@@ -133,17 +116,12 @@ class Config(BaseModel, BaseDB):
提供系统的数据模型定义,用于管理具体的键值对。
"""
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
# ============================================================
# 模型
# ============================================================
class ConfigItem(BaseModel, BaseDB):
"""
模型
@@ -177,74 +155,34 @@ class ConfigItem(BaseModel, BaseDB):
# ============================================================
# 配置ID
config_id = db.Column(
db.Integer,
default=0,
comment="配置ID"
)
config_id = db.Column(db.Integer, default=0, comment="配置ID")
# 配置编码
config_code = db.Column(
db.String(100),
nullable=False,
comment="配置编码"
)
config_code = db.Column(db.String(100), nullable=False, comment="配置编码")
# 名称
name = db.Column(
db.String(100),
nullable=False,
comment="名称"
)
name = db.Column(db.String(100), nullable=False, comment="名称")
# 编码
code = db.Column(
db.String(100),
nullable=False,
comment="编码"
)
code = db.Column(db.String(100), nullable=False, comment="编码")
# 值
value = db.Column(
db.String(1000),
nullable=True,
comment="值"
)
value = db.Column(db.String(1000), nullable=True, comment="值")
# 配置选项
options = db.Column(
db.Text,
nullable=True,
comment="配置选项"
)
options = db.Column(db.Text, nullable=True, comment="配置选项")
# 配置类型
type = db.Column(
db.String(100),
nullable=False,
comment="配置类型"
)
type = db.Column(db.String(100), nullable=False, comment="配置类型")
# 配置状态:1-正常 2-停用
status = db.Column(
db.Integer,
default=1,
comment="配置状态:1-正常 2-停用"
)
status = db.Column(db.Integer, default=1, comment="配置状态:1-正常 2-停用")
# 排序
sort = db.Column(
db.Integer,
default=0,
comment="顺序"
)
sort = db.Column(db.Integer, default=0, comment="顺序")
# 备注
note = db.Column(
db.String(255),
nullable=True,
comment="备注"
)
note = db.Column(db.String(255), nullable=True, comment="备注")
# ============================================================
# 魔法方法
+83 -56
View File
@@ -53,22 +53,25 @@
依赖模块: application.services.config - 参数配置业务逻辑层
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.configuration import service as config
from src.common.utils.request import parse_batch_ids
config_blue = Blueprint('config', __name__, url_prefix='/config')
from src.modules.configuration import service as config_item
from src.common.utils.request import parse_batch_ids, parse_request_body
from src.core import response as R
config_blue = Blueprint("config", __name__, url_prefix="/config")
# ============================================================
# 参数配置分页查询
# ============================================================
@config_blue.route('/page', methods=["GET"])
@config_blue.route("/page", methods=["GET"])
@check_permission("sys:config:page")
def page():
"""
@@ -80,15 +83,15 @@ def page():
Returns:
JSON: 参数配置分页数据,包含 records(数据列表)、total(总记录数)等
"""
result = config.get_config_page()
return result
return R.ok(data=config.get_config_page(request.args))
# ============================================================
# 参数配置详情查询
# ============================================================
@config_blue.route('/detail/<int:id>', methods=["GET"])
@config_blue.route("/detail/<int:id>", methods=["GET"])
@check_permission("sys:config:detail")
def detail(id):
"""
@@ -108,7 +111,8 @@ def detail(id):
# 参数配置添加
# ============================================================
@config_blue.route('/add', methods=["POST"])
@config_blue.route("/add", methods=["POST"])
@check_permission("sys:config:add")
@check_demo
def add():
@@ -121,15 +125,19 @@ def add():
Returns:
JSON: 操作结果
"""
result = config.add_config()
return result
json_data, err = parse_request_body()
if err:
return R.failed(msg=err)
config.add_config(json_data)
return R.ok(msg="添加成功")
# ============================================================
# 参数配置更新
# ============================================================
@config_blue.route('/update', methods=["PUT"])
@config_blue.route("/update", methods=["PUT"])
@check_permission("sys:config:update")
@check_demo
def update():
@@ -142,15 +150,19 @@ def update():
Returns:
JSON: 操作结果
"""
result = config.update_config()
return result
json_data, err = parse_request_body()
if err:
return R.failed(msg=err)
config.update_config(json_data)
return R.ok(msg="更新成功")
# ============================================================
# 参数配置删除
# ============================================================
@config_blue.route('/delete/<string:id>', methods=["DELETE"])
@config_blue.route("/delete/<string:id>", methods=["DELETE"])
@check_permission("sys:config:delete")
@check_demo
def delete(id):
@@ -163,15 +175,16 @@ def delete(id):
Returns:
JSON: 操作结果
"""
result = config.delete_configs(id)
return result
count = config.delete_configs(id)
return R.ok(msg=f"本次共删除{count}条数据")
# ============================================================
# 配置批量删除
# ============================================================
@config_blue.route('/batchDelete', methods=["DELETE"])
@config_blue.route("/batchDelete", methods=["DELETE"])
@check_permission("sys:config:batch_delete")
@check_demo
def batch_delete():
@@ -190,14 +203,16 @@ def batch_delete():
id_str, err = parse_batch_ids()
if err:
return err
return config.delete_configs(id_str)
count = config.delete_configs(id_str)
return R.ok(msg=f"本次共删除{count}条数据")
# ============================================================
# 网站配置查询
# ============================================================
@config_blue.route('/web/index', methods=["GET"])
@config_blue.route("/web/index", methods=["GET"])
@check_permission("sys:configweb:index")
def web_index():
"""
@@ -214,7 +229,8 @@ def web_index():
# 网站配置保存
# ============================================================
@config_blue.route('/web/save', methods=["POST"])
@config_blue.route("/web/save", methods=["POST"])
@check_permission("sys:configweb:save")
@check_demo
def web_save():
@@ -224,10 +240,11 @@ def web_save():
Returns:
JSON: 操作结果
"""
result = config.save_config_data()
return result
json_data, err = parse_request_body()
if err:
return R.failed(msg=err)
config.save_config_data(json_data)
return R.ok(msg="保存成功")
"""
@@ -244,24 +261,19 @@ def web_save():
依赖模块: application.services.config_item - 配置项业务逻辑层
application.middleware.check_permission - 权限校验中间件
"""
from flask import Blueprint
from application.middleware.check_demo import check_demo
from application.middleware.check_permission import check_permission
from src.modules.configuration import service as config_item
from src.common.utils.request import parse_batch_ids
config_item_blue = Blueprint('config_item', __name__, url_prefix='/config/item')
from src.core import response as R
config_item_blue = Blueprint("config_item", __name__, url_prefix="/config/item")
# ============================================================
# 配置项分页查询
# ============================================================
@config_item_blue.route('/page', methods=["GET"])
@config_item_blue.route("/page", methods=["GET"])
@check_permission("sys:configitem:page")
def page():
def config_item_page():
"""
查询配置项分页数据
@@ -271,17 +283,17 @@ def page():
Returns:
JSON: 配置项分页数据,包含 records(数据列表)、total(总记录数)等
"""
result = config_item.get_config_item_page()
return result
return R.ok(data=config_item.get_config_item_page(request.args))
# ============================================================
# 配置项详情查询
# ============================================================
@config_item_blue.route('/detail/<int:id>', methods=["GET"])
@config_item_blue.route("/detail/<int:id>", methods=["GET"])
@check_permission("sys:configitem:detail")
def detail(id):
def config_item_detail(id):
"""
查询配置项详情
@@ -299,10 +311,11 @@ def detail(id):
# 配置项添加
# ============================================================
@config_item_blue.route('/add', methods=["POST"])
@config_item_blue.route("/add", methods=["POST"])
@check_permission("sys:configitem:add")
@check_demo
def add():
def config_item_add():
"""
添加配置项
@@ -312,18 +325,22 @@ def add():
Returns:
JSON: 操作结果
"""
result = config_item.add_config_item()
return result
json_data, err = parse_request_body()
if err:
return R.failed(msg=err)
config_item.add_config_item(json_data)
return R.ok(msg="添加成功")
# ============================================================
# 配置项更新
# ============================================================
@config_item_blue.route('/update', methods=["PUT"])
@config_item_blue.route("/update", methods=["PUT"])
@check_permission("sys:configitem:update")
@check_demo
def update():
def config_item_update():
"""
更新配置项
@@ -333,18 +350,22 @@ def update():
Returns:
JSON: 操作结果
"""
result = config_item.update_config_item()
return result
json_data, err = parse_request_body()
if err:
return R.failed(msg=err)
config_item.update_config_item(json_data)
return R.ok(msg="更新成功")
# ============================================================
# 配置项删除
# ============================================================
@config_item_blue.route('/delete/<string:id>', methods=["DELETE"])
@config_item_blue.route("/delete/<string:id>", methods=["DELETE"])
@check_permission("sys:configitem:delete")
@check_demo
def delete(id):
def config_item_delete(id):
"""
删除配置项
@@ -354,18 +375,19 @@ def delete(id):
Returns:
JSON: 操作结果
"""
result = config_item.delete_config_items(id)
return result
count = config_item.delete_config_items(id)
return R.ok(msg=f"本次共删除{count}条数据")
# ============================================================
# 配置项批量删除
# ============================================================
@config_item_blue.route('/batchDelete', methods=["DELETE"])
@config_item_blue.route("/batchDelete", methods=["DELETE"])
@check_permission("sys:configitem:batch_delete")
@check_demo
def batch_delete():
def config_item_batch_delete():
"""
批量删除配置项
@@ -381,17 +403,19 @@ def batch_delete():
id_str, err = parse_batch_ids()
if err:
return err
return config_item.delete_config_items(id_str)
count = config_item.delete_config_items(id_str)
return R.ok(msg=f"本次共删除{count}条数据")
# ============================================================
# 配置项状态设置
# ============================================================
@config_item_blue.route('/status', methods=["PUT"])
@config_item_blue.route("/status", methods=["PUT"])
@check_permission("sys:configitem:status")
@check_demo
def status():
def config_item_status():
"""
设置配置项状态
@@ -401,5 +425,8 @@ def status():
Returns:
JSON: 操作结果
"""
result = config_item.update_config_item_status()
return result
json_data, err = parse_request_body()
if err:
return R.failed(msg=err)
config_item.update_config_item(json_data)
return R.ok(msg="更新成功")
+56 -93
View File
@@ -58,13 +58,14 @@ from wtforms import IntegerField, StringField
from wtforms.validators import NumberRange, DataRequired, Length, ValidationError, Optional
from src.common.forms.base_form import BaseForm
from src.modules.configuration.models import Config
from src.modules.configuration.models import Config, ConfigItem
# ============================================================
# 配置表单验证(添加和更新共用)
# ============================================================
class ConfigForm(BaseForm):
"""
配置表单验证类
@@ -84,59 +85,45 @@ class ConfigForm(BaseForm):
# 配置ID
# ============================================================
id = IntegerField(
label='配置ID',
validators=[
Optional(), # 允许为空(添加时)
NumberRange(min=1, message='配置ID必须大于0')
],
description='配置唯一标识,更新时必填,添加时自动生成'
label="配置ID",
validators=[Optional(), NumberRange(min=1, message="配置ID必须大于0")], # 允许为空(添加时)
description="配置唯一标识,更新时必填,添加时自动生成",
)
# ============================================================
# 配置名称
# ============================================================
name = StringField(
label='配置名称',
validators=[
DataRequired(message='配置名称不能为空'),
Length(max=100, message='配置名称长度不得超过100个字符')
],
description='配置显示名称'
label="配置名称",
validators=[DataRequired(message="配置名称不能为空"), Length(max=100, message="配置名称长度不得超过100个字符")],
description="配置显示名称",
)
# ============================================================
# 配置编码
# ============================================================
code = StringField(
label='配置编码',
validators=[
DataRequired(message='配置编码不能为空'),
Length(max=100, message='配置编码长度不得超过100个字符')
],
description='配置唯一标识编码,用于程序调用'
label="配置编码",
validators=[DataRequired(message="配置编码不能为空"), Length(max=100, message="配置编码长度不得超过100个字符")],
description="配置唯一标识编码,用于程序调用",
)
# ============================================================
# 配置排序
# ============================================================
sort = IntegerField(
label='配置排序',
validators=[
Optional(),
NumberRange(min=0, max=99999, message='配置排序值在0~99999之间')
],
description='排序值,数值越小越靠前'
label="配置排序",
validators=[Optional(), NumberRange(min=0, max=99999, message="配置排序值在0~99999之间")],
description="排序值,数值越小越靠前",
)
# ============================================================
# 配置备注
# ============================================================
note = StringField(
label='配置备注',
validators=[
Length(max=255, message='配置备注长度不得超过255个字符')
],
description='配置补充说明'
label="配置备注",
validators=[Length(max=255, message="配置备注长度不得超过255个字符")],
description="配置补充说明",
)
# ============================================================
@@ -206,7 +193,6 @@ class ConfigForm(BaseForm):
raise ValidationError("配置编码已存在")
"""
配置项表单验证模块
=============================================================
@@ -216,17 +202,12 @@ class ConfigForm(BaseForm):
- 配置项状态设置表单验证
"""
from wtforms import ValidationError, IntegerField, StringField
from wtforms.validators import NumberRange, DataRequired, Length, Optional
from src.common.forms.base_form import BaseForm
from src.modules.configuration.models import ConfigItem
# ============================================================
# 配置项表单验证(添加和更新共用)
# ============================================================
class ConfigItemForm(BaseForm):
"""
配置项表单验证类
@@ -250,106 +231,90 @@ class ConfigItemForm(BaseForm):
# 配置项ID
# ============================================================
id = IntegerField(
label='配置项ID',
validators=[
Optional(), # 允许为空(添加时)
NumberRange(min=1, message='配置项ID必须大于0')
],
description='配置项唯一标识,更新时必填,添加时自动生成'
label="配置项ID",
validators=[Optional(), NumberRange(min=1, message="配置项ID必须大于0")], # 允许为空(添加时)
description="配置项唯一标识,更新时必填,添加时自动生成",
)
# ============================================================
# 配置ID
# ============================================================
configId = IntegerField(
label='配置ID',
validators=[
DataRequired(message='配置ID不能为空'),
NumberRange(min=0, message='配置ID不得小于0')
],
description='配置ID'
label="配置ID",
validators=[DataRequired(message="配置ID不能为空"), NumberRange(min=0, message="配置ID不得小于0")],
description="配置ID",
)
# ============================================================
# 配置项名称
# ============================================================
name = StringField(
label='配置项名称',
label="配置项名称",
validators=[
DataRequired(message='配置项名称不能为空'),
Length(max=100, message='配置项名称长度不得超过100个字符')
DataRequired(message="配置项名称不能为空"),
Length(max=100, message="配置项名称长度不得超过100个字符"),
],
description='配置项显示标题'
description="配置项显示标题",
)
# ============================================================
# 配置项编码
# ============================================================
code = StringField(
label='配置项编码',
label="配置项编码",
validators=[
DataRequired(message='配置项编码不能为空'),
Length(max=100, message='配置项编码长度不得超过100个字符')
DataRequired(message="配置项编码不能为空"),
Length(max=100, message="配置项编码长度不得超过100个字符"),
],
description='配置项唯一标识编码'
description="配置项唯一标识编码",
)
# ============================================================
# 配置项值
# ============================================================
value = StringField(
label='配置项值',
label="配置项值",
validators=[
DataRequired(message='配置项值不能为空'),
Length(max=1000, message='配置项值长度不得超过1000个字符')
DataRequired(message="配置项值不能为空"),
Length(max=1000, message="配置项值长度不得超过1000个字符"),
],
description='配置项存储值'
description="配置项存储值",
)
# ============================================================
# 配置选项
# ============================================================
options = StringField(
label='配置选项',
validators=[
Length(max=1000, message='配置选项长度不得超过1000个字符')
],
description='配置项可选值列表,用于下拉选择等场景'
label="配置选项",
validators=[Length(max=1000, message="配置选项长度不得超过1000个字符")],
description="配置项可选值列表,用于下拉选择等场景",
)
# ============================================================
# 配置类型
# ============================================================
type = StringField(
label='配置类型',
validators=[
DataRequired(message='配置类型不能为空'),
Length(max=100, message='配置类型长度不得超过100个字符')
],
description='配置项数据类型,如:text、number、select等'
label="配置类型",
validators=[DataRequired(message="配置类型不能为空"), Length(max=100, message="配置类型长度不得超过100个字符")],
description="配置项数据类型,如:text、number、select等",
)
# ============================================================
# 配置项排序
# ============================================================
sort = IntegerField(
label='配置项排序',
validators=[
Optional(),
NumberRange(min=0, max=99999, message='配置项排序值在0~99999之间')
],
description='排序值,数值越小越靠前'
label="配置项排序",
validators=[Optional(), NumberRange(min=0, max=99999, message="配置项排序值在0~99999之间")],
description="排序值,数值越小越靠前",
)
# ============================================================
# 配置项备注
# ============================================================
note = StringField(
label='配置项备注',
validators=[
Length(max=255, message='配置项备注长度不得超过255个字符')
],
description='配置项补充说明'
label="配置项备注",
validators=[Length(max=255, message="配置项备注长度不得超过255个字符")],
description="配置项补充说明",
)
# ============================================================
@@ -415,6 +380,7 @@ class ConfigItemForm(BaseForm):
# 状态设置表单
# ============================================================
class ConfigItemStatusForm(BaseForm):
"""
配置项状态设置表单验证类
@@ -430,22 +396,19 @@ class ConfigItemStatusForm(BaseForm):
# 配置项ID
# ============================================================
id = IntegerField(
label='配置项ID',
validators=[
DataRequired(message='配置项ID不能为空'),
NumberRange(min=1, message='配置项ID必须大于0')
],
description='要修改状态的配置项ID'
label="配置项ID",
validators=[DataRequired(message="配置项ID不能为空"), NumberRange(min=1, message="配置项ID必须大于0")],
description="要修改状态的配置项ID",
)
# ============================================================
# 配置项状态
# ============================================================
status = IntegerField(
label='配置项状态',
label="配置项状态",
validators=[
DataRequired(message='配置项状态不能为空'),
NumberRange(min=1, max=2, message='配置项状态值在1~2之间')
DataRequired(message="配置项状态不能为空"),
NumberRange(min=1, max=2, message="配置项状态值在1~2之间"),
],
description='目标状态:1-在用,2-停用'
description="目标状态:1-在用,2-停用",
)
+174 -297
View File
@@ -65,19 +65,18 @@ from collections import defaultdict
from datetime import datetime, timezone
from typing import List, Dict, Any
from flask import request
from sqlalchemy import and_
from src.common.constants.common import PAGE_SIZE
from src.modules.configuration.schema import ConfigForm
from src.modules.configuration.models import Config
from src.modules.configuration.models import ConfigItem
from src.core.database import db
from src.core import response as R
from src.common.constants.dictionary_constants import CONFIG_ITEM_TYPE_LIST
from src.modules.configuration.schema import ConfigForm, ConfigItemForm, ConfigItemStatusForm
from src.modules.configuration.models import Config, ConfigItem
from src.modules.configuration.config_repository import ConfigRepository
from src.modules.configuration.config_item_repository import ConfigItemRepository
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.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 +88,8 @@ logger = logging.getLogger(__name__)
# 参数配置分页查询
# ============================================================
def get_config_page():
def get_config_page(params: dict) -> dict:
"""
查询参数配置分页数据
@@ -110,31 +110,26 @@ def get_config_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
# 分页查询
config_list = query.limit(page_size).offset((page_no - 1) * page_size).all()
# 构建返回数据
pageData = _build_page_data(config_list, total, page_size, page_no, pages)
return R.ok(data=pageData)
except Exception as e:
logger.error(f"查询参数配置分页数据异常: {str(e)}")
return R.failed(msg="查询失败,请稍后重试")
# 分页查询
config_list = query.limit(page_size).offset((page_no - 1) * page_size).all()
# 构建返回数据
pageData = _build_page_data(config_list, total, page_size, page_no, pages)
return pageData
def _apply_filters():
def _apply_filters(params: dict):
"""
应用查询筛选条件
@@ -151,12 +146,12 @@ def _apply_filters():
query = Config.query.filter(Config.is_delete == 0)
# 配置名称模糊筛选
name = request.args.get('name')
name = params.get("name")
if name:
query = query.filter(Config.name.like(like_contains(name), escape='\\'))
query = query.filter(Config.name.like(like_contains(name), escape="\\"))
# 配置状态精确筛选
status = request.args.get('status')
status = params.get("status")
if status:
query = query.filter(Config.status == status)
@@ -181,19 +176,14 @@ def _build_page_data(config_list, total, page_size, page_no, pages):
# 将模型对象列表转换为字典列表
records = models_to_list(config_list)
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_config_detail(config_id):
"""
根据ID查询参数配置详情(返回字典格式)
@@ -224,6 +214,7 @@ def get_config_detail(config_id):
# 参数配置信息查询(根据ID)- 核心查询方法
# ============================================================
def get_info(config_id: int):
"""
根据ID查询参数配置信息(返回模型对象)
@@ -248,26 +239,10 @@ def get_info(config_id: int):
if config:
print(config.name)
"""
# 参数有效性验证
if not config_id or config_id <= 0:
return None
try:
# 查询未删除的参数配置
config = Config.query.filter(
and_(Config.id == config_id, Config.is_delete == 0)
).first()
return config
except Exception as e:
logger.error(f"查询参数配置信息异常,ID: {config_id}, 错误: {str(e)}")
return None
return ConfigRepository.get_by_id(config_id)
# ============================================================
# 参数配置添加
# ============================================================
def add_config():
def add_config(data: dict) -> None:
"""
添加参数配置
@@ -279,35 +254,24 @@ def add_config():
Returns:
R: 操作结果
"""
try:
# 获取参数
json_data, error = parse_request_body()
if error:
return R.failed(msg=error)
# 表单验证
form = ConfigForm(data=json_data)
if not form.validate():
err_msg = regular.get_err(form)
return R.failed(msg=err_msg)
# 表单验证
form = ConfigForm(data=data)
if not form.validate():
raise BizError(regular.get_err(form))
# 创建参数配置
config = Config(**form.data)
config.create_user = get_username()
config.save()
return R.ok(msg="添加成功")
except Exception as e:
logger.error(f"添加参数配置异常: {str(e)}")
return R.failed(msg="添加失败,请稍后重试")
# 创建参数配置
config = Config(**form.data)
config.create_user = get_username()
config.save()
# ============================================================
# 参数配置更新
# ============================================================
def update_config():
def update_config(data: dict) -> None:
"""
更新参数配置
@@ -320,52 +284,42 @@ def update_config():
Returns:
R: 操作结果
"""
try:
# 获取参数
json_data, error = parse_request_body()
if error:
return R.failed(msg=error)
# 表单验证
form = ConfigForm(data=json_data)
if not form.validate():
return R.failed(msg=regular.get_err(form))
# 表单验证
form = ConfigForm(data=data)
if not form.validate():
raise BizError(regular.get_err(form))
# 获取参数配置ID
config_id = form.data.get('id')
if not config_id or int(config_id) <= 0:
return R.failed("参数配置ID无效")
config_id = int(config_id)
# 获取参数配置ID
config_id = form.data.get("id")
if not config_id or int(config_id) <= 0:
raise BizError("参数配置ID无效")
config_id = int(config_id)
# 复用 get_info 方法验证参数配置是否存在
config = get_info(config_id)
if not config:
return R.failed("参数配置不存在")
# 复用 get_info 方法验证参数配置是否存在
config = get_info(config_id)
if not config:
raise BizError("参数配置不存在")
# 更新参数配置信息(移除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 = Config.query.filter_by(id=config_id).update(form_data)
result = Config.query.filter_by(id=config_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_configs(config_ids):
def delete_configs(config_ids: str) -> int:
"""
删除参数配置(批量删除)
@@ -378,13 +332,17 @@ def delete_configs(config_ids):
Returns:
R: 操作结果
"""
return Config.batch_delete_r(config_ids)
config_ids_list = parse_id_list(config_ids)
if not config_ids_list:
raise BizError("无效的记录ID")
return Config.batch_delete(config_ids_list)
# ============================================================
# 网站配置管理
# ============================================================
def get_config_data() -> List[Dict[str, Any]]:
"""
获取系统配置(优化版,使用一次查询获取所有数据)
@@ -393,9 +351,7 @@ def get_config_data() -> List[Dict[str, Any]]:
返回格式化的配置数据列表
"""
# 查询所有配置
configs = Config.query.filter(
Config.is_delete == 0
).order_by(Config.sort.asc()).all()
configs = Config.query.filter(Config.is_delete == 0).order_by(Config.sort.asc()).all()
if not configs:
return []
@@ -404,11 +360,11 @@ def get_config_data() -> List[Dict[str, Any]]:
config_ids = [config.id for config in configs]
# 一次性查询所有配置项
all_items = ConfigItem.query.filter(
ConfigItem.is_delete == 0,
ConfigItem.status == 1,
ConfigItem.config_id.in_(config_ids)
).order_by(ConfigItem.sort.asc()).all()
all_items = (
ConfigItem.query.filter(ConfigItem.is_delete == 0, ConfigItem.status == 1, ConfigItem.config_id.in_(config_ids))
.order_by(ConfigItem.sort.asc())
.all()
)
# 按配置ID分组
items_by_config = defaultdict(list)
@@ -418,11 +374,7 @@ def get_config_data() -> List[Dict[str, Any]]:
# 构建返回数据
config_list = []
for config in configs:
config_data = {
"configId": config.id,
"configName": config.name,
"dataList": []
}
config_data = {"configId": config.id, "configName": config.name, "dataList": []}
for item in items_by_config.get(config.id, []):
item_data = _process_config_item(item)
@@ -445,9 +397,9 @@ def _process_config_item(item) -> Dict[str, Any]:
处理后的配置项数据
"""
data = model_to_dict(item)
item_type = data.get('type')
item_value = data.get('value')
item_options = data.get('options')
item_type = data.get("type")
item_value = data.get("value")
item_options = data.get("options")
# 处理选项类型(array, radio, checkbox, select, selects)
option_types = ["array", "radio", "checkbox", "select", "selects"]
@@ -528,7 +480,7 @@ def get_content_url(content: str) -> str:
return content
def save_config_data():
def save_config_data(data: dict) -> None:
"""
保存网站配置数据
@@ -537,9 +489,8 @@ def save_config_data():
2. 遍历处理表单数据(列表类型、图片URL等)
3. 根据编码查询配置项并更新值
"""
data, error = parse_request_body()
if error:
return R.failed(msg=error)
if not data:
return
if data:
for key in data:
@@ -553,7 +504,7 @@ def save_config_data():
item.append(url)
else:
item.append(v)
val = ','.join(item)
val = ",".join(item)
else:
if isinstance(val, str) and (val.startswith("http://") or val.startswith("https://")):
val = save_file(val, "config")
@@ -566,9 +517,6 @@ def save_config_data():
config_item.value = val
config_item.save()
return R.ok()
"""
配置项管理服务模块
@@ -592,24 +540,6 @@ def save_config_data():
4. 状态管理:单独更新配置项的启用/禁用状态
"""
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 CONFIG_ITEM_TYPE_LIST
from src.modules.configuration.schema import ConfigItemForm, ConfigItemStatusForm
from src.modules.configuration.models import Config
from src.modules.configuration.models import ConfigItem
from src.core.database import db
from src.core import response as R
from src.common.utils import regular
from src.common.utils.case_converter import convert_camel_to_snake
from src.common.utils.model_utils import model_to_dict
from src.common.utils.request import parse_request_body, parse_id_list, like_contains
from src.core.security import get_username
# 获取日志记录器
logger = logging.getLogger(__name__)
@@ -619,7 +549,8 @@ logger = logging.getLogger(__name__)
# 配置项分页查询
# ============================================================
def get_config_item_page():
def get_config_item_page(params: dict) -> dict:
"""
查询配置项分页数据
@@ -641,31 +572,26 @@ def get_config_item_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_config_item_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
# 分页查询
config_item_list = query.limit(page_size).offset((page_no - 1) * page_size).all()
# 构建返回数据
page_data = _build_page_data(config_item_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="查询失败,请稍后重试")
# 分页查询
config_item_list = query.limit(page_size).offset((page_no - 1) * page_size).all()
# 构建返回数据
page_data = _build_config_item_page_data(config_item_list, total, page_size, page_no, pages)
return page_data
def _apply_filters():
def _apply_config_item_filters(params: dict):
"""
应用查询筛选条件
@@ -683,17 +609,17 @@ def _apply_filters():
query = ConfigItem.query.filter(ConfigItem.is_delete == 0)
# 配置ID筛选(必填)
config_id = request.args.get('configId', 0)
config_id = params.get("configId", 0)
if config_id:
query = query.filter(ConfigItem.config_id == config_id)
# 配置项名称模糊筛选
name = request.args.get('name')
name = params.get("name")
if name:
query = query.filter(ConfigItem.name.like(like_contains(name), escape='\\'))
query = query.filter(ConfigItem.name.like(like_contains(name), escape="\\"))
# 配置项状态精确筛选
status = request.args.get('status')
status = params.get("status")
if status:
query = query.filter(ConfigItem.status == status)
@@ -701,7 +627,7 @@ def _apply_filters():
return query.order_by(ConfigItem.sort.asc())
def _build_page_data(config_item_list, total, page_size, page_no, pages):
def _build_config_item_page_data(config_item_list, total, page_size, page_no, pages):
"""
构建分页返回数据
@@ -720,22 +646,17 @@ def _build_page_data(config_item_list, total, page_size, page_no, pages):
for item in config_item_list:
data = model_to_dict(item)
# 添加配置项类型描述
data['typeName'] = CONFIG_ITEM_TYPE_LIST.get(item.type)
data["typeName"] = CONFIG_ITEM_TYPE_LIST.get(item.type)
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_config_item_detail(config_item_id):
"""
根据ID查询配置项详情(返回字典格式)
@@ -751,7 +672,7 @@ def get_config_item_detail(config_item_id):
"""
try:
# 复用 get_info 方法查询配置项
config_item = get_info(config_item_id)
config_item = get_config_item_info(config_item_id)
if not config_item:
return None
# 转换为字典格式
@@ -766,7 +687,8 @@ def get_config_item_detail(config_item_id):
# 配置项信息查询(根据ID)- 核心查询方法
# ============================================================
def get_info(config_item_id: int):
def get_config_item_info(config_item_id: int):
"""
根据ID查询配置项信息(返回模型对象)
@@ -787,30 +709,14 @@ def get_info(config_item_id: int):
configItem/None: 配置项模型对象,不存在或已删除时返回 None
Example:
config_item = get_info(config_item_id)
config_item = get_config_item_info(config_item_id)
if config_item:
print(config_item.title)
"""
# 参数有效性验证
if not config_item_id or config_item_id <= 0:
return None
try:
# 查询未删除的配置项
config_item = ConfigItem.query.filter(
and_(ConfigItem.id == config_item_id, ConfigItem.is_delete == 0)
).first()
return config_item
except Exception as e:
logger.error(f"查询配置项信息异常,ID: {config_item_id}, 错误: {str(e)}")
return None
return ConfigItemRepository.get_by_id(config_item_id)
# ============================================================
# 配置项添加
# ============================================================
def add_config_item():
def add_config_item(data: dict) -> None:
"""
添加配置项
@@ -822,42 +728,31 @@ def add_config_item():
Returns:
R: 操作结果
"""
try:
# 获取参数
json_data, error = parse_request_body()
if error:
return R.failed(msg=error)
# 表单验证
form = ConfigItemForm(data=json_data)
if not form.validate():
err_msg = regular.get_err(form)
return R.failed(msg=err_msg)
# 表单验证
form = ConfigItemForm(data=data)
if not form.validate():
raise BizError(regular.get_err(form))
# 查询配置(验证配置是否存在)
config_id = form.configId.data
config = Config.query.filter(Config.id == config_id).first()
if not config:
return R.failed(msg="配置不存在")
# 查询配置(验证配置是否存在)
config_id = form.configId.data
config = Config.query.filter(Config.id == config_id).first()
if not config:
raise BizError("配置不存在")
# 创建配置项
config_item = ConfigItem(**form.data)
config_item.config_code = config.code
config_item.create_user = get_username()
config_item.save()
return R.ok(msg="添加成功")
except Exception as e:
logger.error(f"添加配置项异常: {str(e)}")
return R.failed(msg="添加失败,请稍后重试")
# 创建配置项
config_item = ConfigItem(**form.data)
config_item.config_code = config.code
config_item.create_user = get_username()
config_item.save()
# ============================================================
# 配置项更新
# ============================================================
def update_config_item():
def update_config_item(data: dict) -> None:
"""
更新配置项
@@ -870,49 +765,39 @@ def update_config_item():
Returns:
R: 操作结果
"""
try:
# 获取参数
json_data, error = parse_request_body()
if error:
return R.failed(msg=error)
# 表单验证
form = ConfigItemForm(data=json_data)
if not form.validate():
return R.failed(msg=regular.get_err(form))
# 表单验证
form = ConfigItemForm(data=data)
if not form.validate():
raise BizError(regular.get_err(form))
# 获取配置项ID
config_item_id = form.data.get('id')
if not config_item_id or int(config_item_id) <= 0:
return R.failed("配置项ID无效")
# 获取配置项ID
config_item_id = form.data.get("id")
if not config_item_id or int(config_item_id) <= 0:
raise BizError("配置项ID无效")
# 复用 get_info 方法验证配置项是否存在
config_item = get_info(config_item_id)
if not config_item:
return R.failed("配置项不存在")
# 复用 get_info 方法验证配置项是否存在
config_item = get_config_item_info(config_item_id)
if not config_item:
raise BizError("配置项不存在")
# 更新配置项信息(移除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()
result = ConfigItem.query.filter_by(id=config_item_id).update(form_data)
# 更新配置项信息(移除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()
result = ConfigItem.query.filter_by(id=config_item_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_config_items(config_item_ids):
def delete_config_items(config_item_ids: str) -> int:
"""
删除配置项(批量删除)
@@ -925,14 +810,18 @@ def delete_config_items(config_item_ids):
Returns:
R: 操作结果
"""
return ConfigItem.batch_delete_r(config_item_ids)
config_item_ids_list = parse_id_list(config_item_ids)
if not config_item_ids_list:
raise BizError("无效的记录ID")
return ConfigItem.batch_delete(config_item_ids_list)
# ============================================================
# 配置项状态设置
# ============================================================
def update_config_item_status():
def update_config_item_status(data: dict) -> None:
"""
设置配置项状态
@@ -941,35 +830,23 @@ def update_config_item_status():
Returns:
R: 操作结果
"""
try:
# 获取参数
json_data, error = parse_request_body()
if error:
return R.failed(msg=error)
# 表单验证
form = ConfigItemStatusForm(data=json_data)
if not form.validate():
err_msg = regular.get_err(form)
return R.failed(msg=err_msg)
# 表单验证
form = ConfigItemStatusForm(data=data)
if not form.validate():
raise BizError(regular.get_err(form))
config_item_id = int(form.data['id'])
status = int(form.data['status'])
config_item_id = int(form.data["id"])
status = int(form.data["status"])
# 复用 get_info 方法验证配置项是否存在
config_item = get_info(config_item_id)
if not config_item:
return R.failed("配置项不存在")
# 复用 get_info 方法验证配置项是否存在
config_item = get_config_item_info(config_item_id)
if not config_item:
raise BizError("配置项不存在")
# 更新状态
update_data = {"status": status, "update_time": datetime.now(tz=timezone.utc), "update_user": get_username()}
result = ConfigItem.query.filter_by(id=config_item_id).update(update_data)
# 更新状态
update_data = {"status": status, "update_time": datetime.now(tz=timezone.utc), "update_user": get_username()}
result = ConfigItem.query.filter_by(id=config_item_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("设置失败")