refactor(test): 重构测试套件结构并优化测试配置
feat(test-suite): 新增测试套件模块,包含API测试客户端和测试配置 fix(api): 修复数据库实体和仓库的删除操作返回值 style(api): 统一数据库表名和字段命名 perf(api): 添加缓存注解提升配置查询性能 test(api): 添加H2测试数据库配置支持 chore: 清理旧的测试文件和脚本
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
"""
|
||||
字符串处理工具类
|
||||
|
||||
提供字符串相关的工具方法
|
||||
|
||||
作者: 张翔
|
||||
日期: 2026-04-01
|
||||
"""
|
||||
|
||||
import random
|
||||
import string
|
||||
import re
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class StringHelper:
|
||||
"""字符串处理工具类"""
|
||||
|
||||
@staticmethod
|
||||
def truncate(text: str, max_length: int = 100, suffix: str = "...") -> str:
|
||||
"""
|
||||
截断字符串
|
||||
|
||||
Args:
|
||||
text: 原始字符串
|
||||
max_length: 最大长度
|
||||
suffix: 后缀
|
||||
|
||||
Returns:
|
||||
截断后的字符串
|
||||
"""
|
||||
if not text:
|
||||
return ""
|
||||
|
||||
if len(text) <= max_length:
|
||||
return text
|
||||
|
||||
return text[:max_length] + suffix
|
||||
|
||||
@staticmethod
|
||||
def mask_phone(phone: str) -> str:
|
||||
"""
|
||||
手机号脱敏
|
||||
|
||||
Args:
|
||||
phone: 手机号
|
||||
|
||||
Returns:
|
||||
脱敏后的手机号
|
||||
"""
|
||||
if not phone or len(phone) < 7:
|
||||
return phone
|
||||
|
||||
return phone[:3] + "****" + phone[-4:]
|
||||
|
||||
@staticmethod
|
||||
def mask_email(email: str) -> str:
|
||||
"""
|
||||
邮箱脱敏
|
||||
|
||||
Args:
|
||||
email: 邮箱
|
||||
|
||||
Returns:
|
||||
脱敏后的邮箱
|
||||
"""
|
||||
if not email or "@" not in email:
|
||||
return email
|
||||
|
||||
parts = email.split("@")
|
||||
username = parts[0]
|
||||
domain = parts[1]
|
||||
|
||||
if len(username) <= 2:
|
||||
masked_username = username[0] + "***"
|
||||
else:
|
||||
masked_username = username[:2] + "***"
|
||||
|
||||
return f"{masked_username}@{domain}"
|
||||
|
||||
@staticmethod
|
||||
def mask_id_card(id_card: str) -> str:
|
||||
"""
|
||||
身份证号脱敏
|
||||
|
||||
Args:
|
||||
id_card: 身份证号
|
||||
|
||||
Returns:
|
||||
脱敏后的身份证号
|
||||
"""
|
||||
if not id_card or len(id_card) < 8:
|
||||
return id_card
|
||||
|
||||
return id_card[:4] + "**********" + id_card[-4:]
|
||||
|
||||
@staticmethod
|
||||
def random_string(length: int = 16, chars: str = None) -> str:
|
||||
"""
|
||||
生成随机字符串
|
||||
|
||||
Args:
|
||||
length: 长度
|
||||
chars: 字符集,默认为字母数字
|
||||
|
||||
Returns:
|
||||
随机字符串
|
||||
"""
|
||||
if chars is None:
|
||||
chars = string.ascii_letters + string.digits
|
||||
|
||||
return ''.join(random.choice(chars) for _ in range(length))
|
||||
|
||||
@staticmethod
|
||||
def camel_to_snake(name: str) -> str:
|
||||
"""
|
||||
驼峰命名转下划线命名
|
||||
|
||||
Args:
|
||||
name: 驼峰命名字符串
|
||||
|
||||
Returns:
|
||||
下划线命名字符串
|
||||
"""
|
||||
if not name:
|
||||
return ""
|
||||
|
||||
s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
|
||||
return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()
|
||||
|
||||
@staticmethod
|
||||
def snake_to_camel(name: str) -> str:
|
||||
"""
|
||||
下划线命名转驼峰命名
|
||||
|
||||
Args:
|
||||
name: 下划线命名字符串
|
||||
|
||||
Returns:
|
||||
驼峰命名字符串
|
||||
"""
|
||||
if not name:
|
||||
return ""
|
||||
|
||||
components = name.split('_')
|
||||
return components[0] + ''.join(x.title() for x in components[1:])
|
||||
|
||||
@staticmethod
|
||||
def is_empty(text: Optional[str]) -> bool:
|
||||
"""
|
||||
判断字符串是否为空
|
||||
|
||||
Args:
|
||||
text: 字符串
|
||||
|
||||
Returns:
|
||||
是否为空
|
||||
"""
|
||||
return text is None or text.strip() == ""
|
||||
|
||||
@staticmethod
|
||||
def default_if_empty(text: Optional[str], default: str) -> str:
|
||||
"""
|
||||
如果字符串为空则返回默认值
|
||||
|
||||
Args:
|
||||
text: 字符串
|
||||
default: 默认值
|
||||
|
||||
Returns:
|
||||
字符串或默认值
|
||||
"""
|
||||
return text if not StringHelper.is_empty(text) else default
|
||||
Reference in New Issue
Block a user