新增代码
This commit is contained in:
201
difyPlugin/app/services/workcase/qrcode/QrCodeService.py
Normal file
201
difyPlugin/app/services/workcase/qrcode/QrCodeService.py
Normal file
@@ -0,0 +1,201 @@
|
||||
"""二维码服务层 - 提供统一的业务逻辑接口"""
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user