简道云V2.0

This commit is contained in:
z66
2025-11-14 11:04:01 +08:00
parent 073f0646a1
commit 49fc75214f
33 changed files with 1811 additions and 4454 deletions
+154 -13
View File
@@ -1,26 +1,57 @@
"""
F6 插件模块
本模块提供 F6 插件相关的功能,包括:
- 文件上传和校验
- 品牌批量创建
- 历史记录删除
- 客户信息管理
- 车辆信息管理
依赖:
- requests: HTTP 请求
- pandas: Excel 文件处理
- threading: 后台任务处理
"""
import requests
from urllib.parse import quote
import pandas as pd
import os
import urllib.parse
from datetime import datetime
from app.api import API
from typing import Optional, Dict, Any, Tuple
from app.config import Config
from app.module import F6Module
import threading
from app import back_ground_tasks
from app.api import API
from app.config import Config
from app.module.module import F6Module
from app.tasks.brand_tasks import create_brand_background
from app.tasks.delete_tasks import (
delete_history_background,
delete_customer_background,
delete_car_background
)
from app.tasks.customer_tasks import modify_customer_info_background
from app.tasks.bi_tasks import bi_task_background
# 简道云 API 实例,用于调用简道云 API
api_instance = API()
class F6PluginModule:
"""
F6 插件模块类
提供 F6 插件相关的所有功能,包括文件处理、品牌管理、数据删除等。
"""
@staticmethod
def accept_file(data: Dict[str, Any]) -> Tuple[Optional[str], Dict[str, Any]]: # 接收文件
def accept_file(data: Dict[str, Any]) -> Tuple[Optional[str], Dict[str, Any]]:
"""
接收文件
接收文件
处理前端上传的文件,下载文件并保存到指定目录。
此方法用于处理前端上传的文件,下载文件并保存到指定目录。主要步骤包括:
1. 处理前端传递的数据,获取文件的URL。
2. 解析URL以获取文件名。
@@ -147,7 +178,19 @@ class F6PluginModule:
@staticmethod
def create_brand(data: Dict[str, Any]) -> Dict[str, str]: # 创建品牌
def create_brand(data: Dict[str, Any]) -> Dict[str, str]:
"""
创建品牌
从简道云获取品牌创建请求,读取 Excel 文件,并在后台线程中批量创建品牌。
立即返回"正在执行"的提示,实际创建在后台线程中执行。
Args:
data: 包含表单ID(api_key)、表单ID(entry_id)、数据ID(data_id)的字典
Returns:
Dict[str, str]: 包含执行状态的字典,{'msg': '正在执行', 'msg_details': '正在执行,请稍后看结果'}
"""
entry_data = api_instance.entry_data_get(data=data)
print('执行 品牌批量新建')
username = entry_data['data']['账号']
@@ -167,7 +210,7 @@ class F6PluginModule:
cookies = requests.utils.dict_from_cookiejar(login_response.cookies)
try:
thread = threading.Thread(target=back_ground_tasks.create_brand_background,
thread = threading.Thread(target=create_brand_background,
args=(data, cookies, df, save_path))
thread.start()
except Exception as e:
@@ -177,6 +220,18 @@ class F6PluginModule:
@staticmethod
def delete_history(data: Dict[str, Any]) -> Dict[str, str]:
"""
删除历史记录
从简道云获取删除历史记录请求,在后台线程中删除指定门店的历史维修记录。
立即返回"正在执行中"的提示,实际删除在后台线程中执行。
Args:
data: 包含表单ID(api_key)、表单ID(entry_id)、数据ID(data_id)的字典
Returns:
Dict[str, str]: 包含执行状态的字典
"""
entry_data = api_instance.entry_data_get(data=data)
username = entry_data['data']['账号']
password = entry_data['data']['密码']
@@ -202,7 +257,7 @@ class F6PluginModule:
org_id = org['orgId']
if org_id:
thread = threading.Thread(target=back_ground_tasks.delete_history_background,
thread = threading.Thread(target=delete_history_background,
args=(data, cookies, org_id, org_name1))
thread.start()
return {'msg': '正在执行中', 'msg_details': '请稍后查看结果'}
@@ -211,6 +266,18 @@ class F6PluginModule:
@staticmethod
def delete_customer(data):
"""
删除客户
从简道云获取删除客户请求,在后台线程中批量删除客户信息。
立即返回"正在执行中"的提示,实际删除在后台线程中执行。
Args:
data: 包含表单ID(api_key)、表单ID(entry_id)、数据ID(data_id)的字典
Returns:
Dict[str, str]: 包含执行状态的字典
"""
entry_data = api_instance.entry_data_get(data=data)
username = entry_data['data']['账号']
password = entry_data['data']['密码']
@@ -225,7 +292,7 @@ class F6PluginModule:
json = res.json()
if json:
thread = threading.Thread(target=back_ground_tasks.delete_customer_background,
thread = threading.Thread(target=delete_customer_background,
args=(data, cookies, json['data']['data'],))
thread.start()
return {'msg': '正在执行中', 'msg_details': '8-20点3.5s一条数据,其余时间1.5s一条数据'}
@@ -236,6 +303,18 @@ class F6PluginModule:
@staticmethod
def delete_cars(data):
"""
删除车辆
从简道云获取删除车辆请求,在后台线程中批量删除客户车辆信息。
立即返回"正在执行中"的提示,实际删除在后台线程中执行。
Args:
data: 包含表单ID(api_key)、表单ID(entry_id)、数据ID(data_id)的字典
Returns:
Dict[str, str]: 包含执行状态的字典
"""
entry_data = api_instance.entry_data_get(data=data)
username = entry_data['data']['账号']
password = entry_data['data']['密码']
@@ -259,7 +338,7 @@ class F6PluginModule:
all_page = total_items // 100 + (total_items % 100 > 0)
if res_data:
thread = threading.Thread(target=back_ground_tasks.delete_car_background,
thread = threading.Thread(target=delete_car_background,
args=(data, url, cookies, header, all_page))
thread.start()
return {'msg': '正在执行中', 'msg_details': '8-20点3.5s一条数据,其余时间1.5s一条数据'}
@@ -270,6 +349,18 @@ class F6PluginModule:
return {'msg': '未执行', 'msg_details': '登录失败'}
def modify_customer_info(self, data: Dict[str, str]):
"""
修改客户信息
从简道云获取修改客户信息请求,读取 Excel 文件,并在后台线程中批量修改客户信息。
立即返回"正在执行中"的提示,实际修改在后台线程中执行。
Args:
data: 包含表单ID(api_key)、表单ID(entry_id)、数据ID(data_id)的字典
Returns:
Dict[str, str]: 包含执行状态的字典
"""
entry_data = api_instance.entry_data_get(data=data)
username = entry_data['data']['账号']
password = entry_data['data']['密码']
@@ -288,11 +379,61 @@ class F6PluginModule:
return {'msg': f'读取Excel文件失败: {str(e)},文件路径:{save_path}'}
if cookies:
thread = threading.Thread(target=back_ground_tasks.modify_customer_info_background,
thread = threading.Thread(target=modify_customer_info_background,
args=(data, cookies, df, save_path))
thread.start()
return {'msg': '正在执行中', 'msg_details': '请稍后查看结果'}
else:
return {'msg': '未执行', 'msg_details': 'cookies获取失败'}
@staticmethod
def bi_task(data: Dict[str, Any]) -> Dict[str, str]:
"""
BI任务
从简道云获取BI任务请求,读取 Excel 文件(如果需要),并在后台线程中执行BI任务。
立即返回"正在执行"的提示,实际执行在后台线程中完成。
Args:
data: 包含表单ID(api_key)、表单ID(entry_id)、数据ID(data_id)的字典
Returns:
Dict[str, str]: 包含执行状态的字典,{'msg': '正在执行', 'msg_details': '正在执行,请稍后看结果'}
"""
entry_data = api_instance.entry_data_get(data=data)
print('执行 BI任务')
# 获取必要的参数(根据实际需求调整)
username = entry_data['data'].get('账号')
password = entry_data['data'].get('密码')
company_name = entry_data['data'].get('公司名称')
save_path = entry_data['data'].get('文件保存地址')
# 如果需要登录F6系统
cookies = None
if username and password and company_name:
login_response = F6Module.login_in(username, password, company_name)
if login_response is None:
return {'msg': '登录失败', 'msg_details': '无法登录F6系统'}
cookies = requests.utils.dict_from_cookiejar(login_response.cookies)
# 如果需要读取Excel文件
df = None
if save_path:
try:
df = pd.read_excel(save_path, sheet_name=0, dtype='string')
except Exception as e:
return {'msg': f'读取Excel文件失败: {str(e)},文件路径:{save_path}'}
# 启动后台线程执行BI任务
try:
thread = threading.Thread(target=bi_task_background,
args=(data, cookies, df, save_path))
thread.start()
except Exception as e:
print(f'创建线程失败: {str(e)}')
return {'msg': '任务启动失败', 'msg_details': f'无法启动后台任务: {str(e)}'}
return {'msg': '正在执行', 'msg_details': '正在执行,请稍后看结果'}
+8
View File
@@ -1,2 +1,10 @@
"""
业务模块包
本包包含所有业务模块,包括:
- module.py: F6Module - F6系统相关功能
- f6_plugin_module.py: F6PluginModule - F6插件功能
- other_module.py: OtherPluginModule - 其他功能模块
"""
__all__ = []
+96 -1
View File
@@ -1,3 +1,18 @@
"""
F6 系统模块
本模块提供 F6 系统相关的功能,包括:
- 登录和认证
- 验证码识别
- 公司信息获取
- 门店信息获取
- 保持连接
依赖:
- requests: HTTP 请求
- PIL: 图像处理
- pytesseract: OCR 识别
"""
import requests
import hashlib
from urllib.parse import quote
@@ -7,15 +22,33 @@ from typing import Optional, Dict, AnyStr
from PIL import Image, ImageEnhance
import pytesseract
import logging
from datetime import datetime
# 简道云 API 实例,用于调用简道云 API
api_instance = API()
# 日志记录器
logger = logging.getLogger('app')
class F6Module:
"""
F6 系统模块类
提供 F6 系统相关的所有功能,包括登录、信息获取等。
"""
@staticmethod
def get_captcha() -> AnyStr:
"""
获取并识别验证码
从 F6 系统获取验证码图片,使用 OCR 识别验证码文本。
Returns:
AnyStr: 识别出的验证码文本
注意:
需要系统安装 Tesseract OCR 才能正常工作
"""
captcha_url = 'https://yunxiu.f6car.cn/kzf6/login/captcha-image'
response = requests.get(captcha_url)
with open('captcha.png', 'wb') as f:
@@ -37,6 +70,23 @@ class F6Module:
@staticmethod
def login_in(username: str, password: str, company_name: str = '默认门店',) -> Optional[requests.Response]:
"""
F6 系统登录
使用用户名和密码登录 F6 系统,并选择指定的公司。
如果触发验证码,会自动识别并重试登录。
Args:
username: 用户名
password: 密码(明文,方法内部会进行 MD5 加密)
company_name: 公司名称,默认为'默认门店'
Returns:
Optional[requests.Response]: 登录响应对象,登录失败返回 None
注意:
密码会在方法内部进行 MD5 加密处理
"""
url = "https://yunxiu.f6car.com/kzf6/login/confirm"
session = requests.Session()
header = {
@@ -82,6 +132,17 @@ class F6Module:
return None
def accept_login_message(self, data: Dict[str, str]) -> Dict[str, str]:
"""
接受登录消息并处理
处理简道云插件发送的登录请求,执行登录并返回结果。
Args:
data: 包含用户名、密码、公司名称的字典
Returns:
Dict[str, str]: 登录结果,包含状态信息
"""
username = data['username']
password = data['password']
company_name = data['company_name']
@@ -110,6 +171,17 @@ class F6Module:
return {"status": "登录失败,请检查公司名称"}
def get_company_information(self, data: Dict[str, str]) -> Dict[str, str]:
"""
获取公司信息
根据用户名和密码获取 F6 系统中的公司信息,并将结果保存到简道云。
Args:
data: 包含用户名、密码的字典
Returns:
Dict[str, str]: 包含时间戳的消息,用于后续查询
"""
username = data['username']
password = data['password']
timestamp = datetime.now().strftime("%Y-%m-%d %H-%M-%S")
@@ -173,6 +245,18 @@ class F6Module:
return res
def get_store_information(self, data: Dict[str, str]) -> Dict[str, dict[str, str]]:
"""
获取门店信息
根据用户名、密码和公司名称获取 F6 系统中的门店信息,
包括门店列表、客户车辆数量、客户数量等。
Args:
data: 包含用户名、密码、公司名称的字典
Returns:
Dict[str, dict[str, str]]: 包含时间戳、门店信息、统计数据的结果
"""
username = data['username']
password = data['password']
company_name = data['company_name']
@@ -221,6 +305,17 @@ class F6Module:
@staticmethod
def get_keep_heart(data: Dict[str, str]) -> Dict[str, str]:
"""
保持连接
用于保持连接的心跳检测,直接返回接收到的数据。
Args:
data: 接收到的数据字典
Returns:
Dict[str, str]: 原样返回接收到的数据
"""
return data
+18 -14
View File
@@ -1,22 +1,26 @@
import requests
from urllib.parse import quote
import pandas as pd
import os
import urllib.parse
from datetime import datetime
from app.api import API
from typing import Optional, Dict, Any, Tuple
from app.config import Config
from app.module import F6Module
import threading
from app import back_ground_tasks
"""
其他插件模块
api_instance = API()
本模块提供其他插件相关的功能,目前包括短信签名状态查询等功能。
"""
class OtherPluginModule:
"""
其他插件模块类
提供其他插件相关的功能,如短信签名状态等。
"""
def sms_signature_status(self):
"""
短信签名状态
查询短信签名状态(待实现)。
Returns:
待实现
"""
pass