简道云V2.0
This commit is contained in:
+154
-13
@@ -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': '正在执行,请稍后看结果'}
|
||||
|
||||
|
||||
|
||||
@@ -1,2 +1,10 @@
|
||||
"""
|
||||
业务模块包
|
||||
|
||||
本包包含所有业务模块,包括:
|
||||
- module.py: F6Module - F6系统相关功能
|
||||
- f6_plugin_module.py: F6PluginModule - F6插件功能
|
||||
- other_module.py: OtherPluginModule - 其他功能模块
|
||||
"""
|
||||
__all__ = []
|
||||
|
||||
|
||||
+96
-1
@@ -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
@@ -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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user