Files
urbanLifeline/difyPlugin/app/services/workcase/qrcode/QrCodeService.py

202 lines
5.5 KiB
Python
Raw Normal View History

2025-12-30 18:37:07 +08:00
"""二维码服务层 - 提供统一的业务逻辑接口"""
import base64
from typing import Optional
from .QrCode import QRCodeProcessor
class QrCodeService:
"""二维码服务 - 业务逻辑层"""
def __init__(self):
"""初始化服务"""
self.processor = QRCodeProcessor()
async def generate_qrcode(
self,
content: str,
size: int = 300,
error_correction: str = "H"
) -> dict:
"""
生成二维码
Args:
content: 二维码内容
size: 图片大小像素
error_correction: 纠错级别 (L/M/Q/H)
Returns:
{
"success": bool,
"image": str, # base64编码的图片
"content": str,
"size": int,
"error_correction": str,
"error": str # 仅失败时有
}
"""
try:
# 验证参数
if not content:
return {
"success": False,
"error": "内容不能为空"
}
if size < 100 or size > 2000:
return {
"success": False,
"error": "尺寸必须在100-2000之间"
}
if error_correction not in ["L", "M", "Q", "H"]:
return {
"success": False,
"error": "纠错级别必须是 L/M/Q/H 之一"
}
# 生成二维码
img_base64 = self.processor.generate(
content=content,
size=size,
error_correction=error_correction
)
return {
"success": True,
"image": img_base64,
"content": content,
"size": size,
"error_correction": error_correction
}
except Exception as e:
return {
"success": False,
"error": f"生成失败: {str(e)}"
}
async def parse_qrcode(
self,
image_source: str,
strategy: str = "auto"
) -> dict:
"""
解析二维码
Args:
image_source: 图片来源URL/base64/本地路径
strategy: 预处理策略 (basic/auto/enhanced/all)
Returns:
{
"success": bool,
"content": str or None,
"strategy_used": str,
"total_attempts": int,
"error": str # 仅失败时有
}
"""
try:
# 验证参数
if not image_source:
return {
"success": False,
"error": "图片来源不能为空"
}
if strategy not in ["basic", "auto", "enhanced", "all"]:
return {
"success": False,
"error": "策略必须是 basic/auto/enhanced/all 之一"
}
# 解析二维码
result = await self.processor.parse(image_source, strategy)
if result["success"]:
return result
else:
return {
"success": False,
"content": None,
"error": result.get("message", "解析失败"),
"total_attempts": result.get("total_attempts", 0)
}
except Exception as e:
return {
"success": False,
"content": None,
"error": f"解析失败: {str(e)}"
}
async def parse_qrcode_from_file(
self,
file_content: bytes,
file_type: str = "png",
strategy: str = "auto"
) -> dict:
"""
从文件内容解析二维码
Args:
file_content: 文件二进制内容
file_type: 文件类型 (png/jpg/jpeg等)
strategy: 预处理策略
Returns:
解析结果格式同parse_qrcode
"""
try:
# 转换为base64
img_base64 = base64.b64encode(file_content).decode()
image_source = f"data:image/{file_type};base64,{img_base64}"
# 调用解析方法
return await self.parse_qrcode(image_source, strategy)
except Exception as e:
return {
"success": False,
"content": None,
"error": f"文件解析失败: {str(e)}"
}
def validate_qrcode_content(self, content: str, max_length: int = 2953) -> dict:
"""
验证二维码内容是否合法
Args:
content: 要验证的内容
max_length: 最大长度默认2953字节version 40 with L级别
Returns:
{
"valid": bool,
"length": int,
"error": str # 仅无效时有
}
"""
if not content:
return {
"valid": False,
"error": "内容不能为空"
}
content_bytes = content.encode("utf-8")
length = len(content_bytes)
if length > max_length:
return {
"valid": False,
"length": length,
"error": f"内容过长,当前{length}字节,最大支持{max_length}字节"
}
return {
"valid": True,
"length": length
}