- git 初始化 + .gitignore 补全(根 .env / logs / instance / __pycache__ 等) - 修复 utils/.gitignore 误将整个 utils/ 源码层忽略的问题,补入全部工具源码(含 ip2region.xdb) - 含后端全部代码:application / extensions / utils / config / migrations - 含前端 ui/(后续整体迁走) - 不含根 .env(含密钥,本地保留) Co-Authored-By: Claude <noreply@anthropic.com>
328 lines
8.0 KiB
Python
328 lines
8.0 KiB
Python
"""
|
|
命名格式转换工具模块
|
|
=============================================================
|
|
|
|
提供字符串命名格式之间的转换功能,主要用于数据库字段名(下划线命名)
|
|
与前端字段名(驼峰命名)之间的转换。
|
|
|
|
主要功能:
|
|
1. 下划线命名 → 驼峰命名
|
|
2. 驼峰命名 → 下划线命名
|
|
3. 下划线命名 → 帕斯卡命名(大驼峰)
|
|
4. 递归转换字典的所有键名
|
|
"""
|
|
|
|
|
|
def convert_camel_case(snake_str):
|
|
"""
|
|
将下划线命名转换为驼峰命名
|
|
|
|
Args:
|
|
snake_str: 下划线命名字符串,如 'create_time'
|
|
|
|
Returns:
|
|
驼峰命名字符串,如 'createTime'
|
|
|
|
Examples:
|
|
>>> convert_camel_case('create_time')
|
|
'createTime'
|
|
>>> convert_camel_case('user_id')
|
|
'userId'
|
|
>>> convert_camel_case('id')
|
|
'id'
|
|
>>> convert_camel_case('')
|
|
''
|
|
"""
|
|
if not snake_str:
|
|
return ''
|
|
|
|
components = snake_str.split('_')
|
|
return components[0] + ''.join(_capitalize_first_letter(x) for x in components[1:])
|
|
|
|
|
|
def convert_snake_case(camel_str):
|
|
"""
|
|
将驼峰命名转换为下划线命名
|
|
|
|
Args:
|
|
camel_str: 驼峰命名字符串,如 'createTime'
|
|
|
|
Returns:
|
|
下划线命名字符串,如 'create_time'
|
|
|
|
Examples:
|
|
>>> convert_snake_case('createTime')
|
|
'create_time'
|
|
>>> convert_snake_case('userId')
|
|
'user_id'
|
|
>>> convert_snake_case('id')
|
|
'id'
|
|
>>> convert_snake_case('')
|
|
''
|
|
"""
|
|
if not camel_str:
|
|
return ''
|
|
|
|
result = []
|
|
for i, char in enumerate(camel_str):
|
|
if char.isupper() and i > 0:
|
|
result.append('_')
|
|
result.append(char.lower())
|
|
else:
|
|
result.append(char.lower())
|
|
|
|
return ''.join(result)
|
|
|
|
|
|
def convert_pascal_case(snake_str):
|
|
"""
|
|
将下划线命名转换为帕斯卡命名(大驼峰)
|
|
|
|
Args:
|
|
snake_str: 下划线命名字符串,如 'create_time'
|
|
|
|
Returns:
|
|
帕斯卡命名字符串,如 'CreateTime'
|
|
|
|
Examples:
|
|
>>> convert_pascal_case('create_time')
|
|
'CreateTime'
|
|
>>> convert_pascal_case('user_id')
|
|
'UserId'
|
|
>>> convert_pascal_case('')
|
|
''
|
|
"""
|
|
if not snake_str:
|
|
return ''
|
|
|
|
components = snake_str.split('_')
|
|
return ''.join(_capitalize_first_letter(x) for x in components)
|
|
|
|
|
|
def convert_dict_keys(data, converter=convert_camel_case):
|
|
"""
|
|
递归转换字典的所有键名
|
|
|
|
Args:
|
|
data: 需要转换的字典或列表
|
|
converter: 转换函数,默认为 to_camel_case
|
|
|
|
Returns:
|
|
转换后的字典或列表
|
|
|
|
Examples:
|
|
>>> data = {'create_time': '2024-01-01', 'user_id': 1}
|
|
>>> convert_dict_keys(data)
|
|
{'createTime': '2024-01-01', 'userId': 1}
|
|
|
|
>>> data = [{'user_name': '张三'}, {'user_name': '李四'}]
|
|
>>> convert_dict_keys(data)
|
|
[{'userName': '张三'}, {'userName': '李四'}]
|
|
"""
|
|
if isinstance(data, list):
|
|
return [convert_dict_keys(item, converter) for item in data]
|
|
|
|
if isinstance(data, dict):
|
|
result = {}
|
|
for key, value in data.items():
|
|
new_key = converter(key)
|
|
result[new_key] = convert_dict_keys(value, converter)
|
|
return result
|
|
|
|
return data
|
|
|
|
|
|
def convert_snake_to_camel(data):
|
|
"""
|
|
将字典中的下划线命名字段转换为驼峰命名(便捷方法)
|
|
|
|
这是 convert_dict_keys 的便捷封装,专门用于数据库字段转前端字段。
|
|
|
|
Args:
|
|
data: 需要转换的字典或列表
|
|
|
|
Returns:
|
|
转换后的字典或列表(所有键名转为驼峰命名)
|
|
|
|
Examples:
|
|
>>> data = {'create_time': '2024-01-01', 'user_id': 1}
|
|
>>> convert_dict_keys_snake_to_camel(data)
|
|
{'createTime': '2024-01-01', 'userId': 1}
|
|
|
|
>>> data = [{'user_name': '张三'}, {'user_name': '李四'}]
|
|
>>> convert_dict_keys_snake_to_camel(data)
|
|
[{'userName': '张三'}, {'userName': '李四'}]
|
|
"""
|
|
return convert_dict_keys(data, converter=convert_camel_case)
|
|
|
|
|
|
def convert_camel_to_snake(data):
|
|
"""
|
|
将字典中的驼峰命名字段转换为下划线命名(便捷方法)
|
|
|
|
这是 convert_dict_keys 的便捷封装,专门用于前端字段转数据库字段。
|
|
|
|
Args:
|
|
data: 需要转换的字典或列表
|
|
|
|
Returns:
|
|
转换后的字典或列表(所有键名转为下划线命名)
|
|
|
|
Examples:
|
|
>>> data = {'createTime': '2024-01-01', 'userId': 1}
|
|
>>> convert_dict_keys_camel_to_snake(data)
|
|
{'create_time': '2024-01-01', 'user_id': 1}
|
|
|
|
>>> data = [{'userName': '张三'}, {'userName': '李四'}]
|
|
>>> convert_dict_keys_camel_to_snake(data)
|
|
[{'user_name': '张三'}, {'user_name': '李四'}]
|
|
"""
|
|
return convert_dict_keys(data, converter=convert_snake_case)
|
|
|
|
|
|
# ============================================================
|
|
# 私有方法
|
|
# ============================================================
|
|
|
|
def _capitalize_first_letter(s):
|
|
"""
|
|
将字符串的首字母大写,其余字母小写
|
|
|
|
Args:
|
|
s: 输入字符串
|
|
|
|
Returns:
|
|
首字母大写后的字符串
|
|
|
|
Examples:
|
|
>>> _capitalize_first_letter('name')
|
|
'Name'
|
|
>>> _capitalize_first_letter('userName')
|
|
'Username'
|
|
>>> _capitalize_first_letter('')
|
|
''
|
|
"""
|
|
if not s:
|
|
return ''
|
|
return s[0].upper() + s[1:].lower()
|
|
|
|
|
|
def _is_camel_case(s):
|
|
"""
|
|
判断字符串是否为驼峰命名格式
|
|
|
|
驼峰命名特征:
|
|
1. 首字母小写
|
|
2. 不包含下划线
|
|
3. 包含大写字母(至少一个大写字母)
|
|
|
|
Args:
|
|
s: 输入字符串
|
|
|
|
Returns:
|
|
bool: 是否为驼峰命名格式
|
|
|
|
Examples:
|
|
>>> _is_camel_case('createTime')
|
|
True
|
|
>>> _is_camel_case('create_time')
|
|
False
|
|
>>> _is_camel_case('id')
|
|
False
|
|
"""
|
|
if not s:
|
|
return False
|
|
|
|
# 首字母必须小写,不包含下划线,且至少有一个大写字母
|
|
return (s[0].islower() and
|
|
'_' not in s and
|
|
any(char.isupper() for char in s))
|
|
|
|
|
|
def _is_snake_case(s):
|
|
"""
|
|
判断字符串是否为下划线命名格式
|
|
|
|
下划线命名特征:
|
|
1. 全部小写
|
|
2. 包含下划线
|
|
3. 不以_开头,不以_结尾
|
|
|
|
Args:
|
|
s: 输入字符串
|
|
|
|
Returns:
|
|
bool: 是否为下划线命名格式
|
|
|
|
Examples:
|
|
>>> _is_snake_case('create_time')
|
|
True
|
|
>>> _is_snake_case('createTime')
|
|
False
|
|
>>> _is_snake_case('id')
|
|
False
|
|
"""
|
|
if not s:
|
|
return False
|
|
|
|
# 全部小写,包含下划线,且不以_开头结尾
|
|
return (s.islower() and
|
|
'_' in s and
|
|
not s.startswith('_') and
|
|
not s.endswith('_'))
|
|
|
|
|
|
def _is_pascal_case(s):
|
|
"""
|
|
判断字符串是否为帕斯卡命名格式(大驼峰)
|
|
|
|
帕斯卡命名特征:
|
|
1. 首字母大写
|
|
2. 不包含下划线
|
|
3. 至少有一个字母
|
|
|
|
Args:
|
|
s: 输入字符串
|
|
|
|
Returns:
|
|
bool: 是否为帕斯卡命名格式
|
|
|
|
Examples:
|
|
>>> _is_pascal_case('CreateTime')
|
|
True
|
|
>>> _is_pascal_case('createTime')
|
|
False
|
|
>>> _is_pascal_case('create_time')
|
|
False
|
|
"""
|
|
if not s:
|
|
return False
|
|
|
|
# 首字母大写,不包含下划线
|
|
return (s[0].isupper() and
|
|
'_' not in s and
|
|
any(char.isalpha() for char in s))
|
|
|
|
|
|
def _convert_single_field(field_name, converter=convert_camel_case):
|
|
"""
|
|
转换单个字段名
|
|
|
|
Args:
|
|
field_name: 字段名
|
|
converter: 转换函数,默认为 to_camel_case
|
|
|
|
Returns:
|
|
转换后的字段名
|
|
|
|
Examples:
|
|
>>> _convert_single_field('create_time')
|
|
'createTime'
|
|
>>> _convert_single_field('createTime', convert_snake_case)
|
|
'create_time'
|
|
"""
|
|
if not field_name:
|
|
return ''
|
|
|
|
return converter(field_name)
|