364 lines
15 KiB
Python
364 lines
15 KiB
Python
"""
|
||
删除相关后台任务模块
|
||
|
||
本模块包含删除相关的后台任务,包括:
|
||
- 删除历史维修记录
|
||
- 删除客户信息
|
||
- 删除客户车辆信息
|
||
|
||
这些任务在后台线程中执行,不会阻塞主请求。
|
||
执行完成后会更新简道云表单并自动提交工作流。
|
||
"""
|
||
import logging
|
||
import traceback
|
||
import requests
|
||
import time
|
||
from typing import Dict, Any, List, Optional
|
||
from datetime import datetime
|
||
from tqdm import tqdm
|
||
from app.tasks.common import update_jiandaoyun, approve_workflow, get_operate_org_id, get_card_list, \
|
||
execute_failure_handler
|
||
|
||
logger = logging.getLogger('app')
|
||
|
||
|
||
def delete_history_background(data: Dict[str, Any], cookies: Dict[str, str], org_id: str, org_name: str):
|
||
"""
|
||
删除历史维修记录后台任务
|
||
|
||
在后台线程中删除指定门店的历史维修记录。
|
||
执行完成后会更新简道云表单并自动提交工作流。
|
||
|
||
Args:
|
||
data: 包含表单ID(api_key)、表单ID(entry_id)、数据ID(data_id)的字典
|
||
cookies: 用户登录 F6 系统的 cookies 信息
|
||
org_id: 需要删除历史维修记录的门店ID
|
||
org_name: 需要删除历史维修记录的门店名称
|
||
|
||
Returns:
|
||
None
|
||
"""
|
||
try:
|
||
|
||
url = f'https://yunxiu.f6car.cn/maintain-dump/maintainHistory/?orgid={org_id}' # 删除url
|
||
res = requests.delete(url=url, cookies=cookies)
|
||
res_data = res.json()
|
||
|
||
if res.status_code == 200 and res_data.get('code') == 200:
|
||
results = f'{org_name} 历史维修记录已删除'
|
||
print(results)
|
||
logger.info(f"删除 {org_name} 历史维修记录成功")
|
||
else:
|
||
results = f'删除 {org_name} 历史维修记录失败: {res_data.get("message")}'
|
||
data["failure_name"] = "删除历史维修记录后台任务"
|
||
data["failure_details"] = results
|
||
execute_failure_handler(data)
|
||
logger.error(f"删除 {org_name} 历史维修记录失败: {res_data.get('message')}")
|
||
|
||
# 调用api回写改掉 执行明细与执行状态
|
||
time.sleep(1)
|
||
msg = update_jiandaoyun(data, f'{results}')
|
||
|
||
if msg.get('msg'):
|
||
approve_workflow(data)
|
||
print('表单已自动提交至下一步')
|
||
except Exception as e:
|
||
logger.error(f"删除 {org_name} 历史维修记录失败: {e}")
|
||
logger.error(traceback.format_exc())
|
||
data["failure_name"] = "删除历史维修记录后台任务"
|
||
data["failure_details"] = traceback.format_exc()
|
||
execute_failure_handler(data)
|
||
|
||
|
||
def delete_customer_background(data: Dict[str, Any], cookies: Dict[str, str], total: int):
|
||
"""
|
||
删除客户信息后台任务
|
||
|
||
在后台线程中批量删除客户信息。
|
||
执行完成后会更新简道云表单并自动提交工作流。
|
||
|
||
Args:
|
||
data: 包含表单ID(api_key)、表单ID(entry_id)、数据ID(data_id)的字典
|
||
cookies: 用户登录 F6 系统的 cookies 信息
|
||
json_data: 获取到的客户信息列表,包含要删除的客户信息
|
||
|
||
Returns:
|
||
None
|
||
|
||
注意:
|
||
- 8-20点之间每3.5秒删除一条数据,其余时间每1.5秒删除一条数据
|
||
- 执行结果会更新到简道云表单
|
||
"""
|
||
try:
|
||
logger.info("开始删除客户信息")
|
||
success = 0
|
||
fail = 0
|
||
|
||
json_data = []
|
||
total_page = total // 100 + (total % 100 > 0)
|
||
logger.info("正在加载客户信息")
|
||
for page in tqdm(range(1, total_page + 1)):
|
||
url = f"https://yunxiu.f6car.cn/member/customer/listForPermission?pageSize=100&pageNo={page}"
|
||
res = requests.get(url, cookies=cookies)
|
||
json_data.extend(res.json().get('data', {}).get('data', []))
|
||
|
||
# 获取门店ID
|
||
operate_org_id = get_operate_org_id(cookies)
|
||
if not operate_org_id:
|
||
msg = update_jiandaoyun(data, '删除失败: 未获取到门店信息')
|
||
if msg.get('msg'):
|
||
approve_workflow(data)
|
||
return
|
||
|
||
|
||
# 获取会员卡列表(提取客户ID)
|
||
card_list_customers = get_card_list(cookies, operate_org_id)
|
||
|
||
for item in tqdm(json_data, desc="删除客户"):
|
||
id_customer = item['idCustomer']
|
||
phone = item['cellPhone']
|
||
consume_last_time = item['consumeLastTime']
|
||
if consume_last_time:
|
||
print(f'{id_customer}最近消费时间: {consume_last_time},跳过删除')
|
||
logger.warning(f"{id_customer}最近消费时间: {consume_last_time},跳过删除")
|
||
continue
|
||
|
||
if id_customer in card_list_customers:
|
||
logger.info(f"{id_customer} 存在会员卡,跳过删除")
|
||
fail += 1
|
||
continue
|
||
|
||
try:
|
||
url = f"https://yunxiu.f6car.cn/member/customer/{id_customer}" # 客户信息删除url
|
||
res = requests.delete(url, cookies=cookies, timeout=10) # 客户信息删除
|
||
|
||
# 检查HTTP状态码
|
||
if res.status_code != 200:
|
||
fail += 1
|
||
error_msg = f"HTTP状态码错误: {res.status_code}"
|
||
logger.error(f"客户删除失败: ID={id_customer}, 手机号={phone}, {error_msg}")
|
||
print(f"删除失败: ID={id_customer}, 手机号={phone}, {error_msg}")
|
||
time.sleep(0.2)
|
||
continue
|
||
|
||
# 解析响应数据
|
||
try:
|
||
res_data = res.json()
|
||
except ValueError as json_error:
|
||
fail += 1
|
||
error_msg = f"响应不是有效的JSON格式: {json_error}, 响应内容: {res.text[:200]}"
|
||
logger.error(f"客户删除失败: ID={id_customer}, 手机号={phone}, {error_msg}")
|
||
print(f"删除失败: ID={id_customer}, 手机号={phone}, {error_msg}")
|
||
time.sleep(0.2)
|
||
continue
|
||
|
||
# 检查多种可能的成功标识
|
||
# 有些API返回 success 字段,有些返回 code=200,有些返回 data 字段
|
||
is_success = (
|
||
res_data.get('success') is True or
|
||
res_data.get('code') == 200 or
|
||
(res_data.get('code') is None and res_data.get('data') is not None)
|
||
)
|
||
|
||
if is_success:
|
||
success += 1
|
||
logger.info(f"客户删除成功: ID={id_customer}, 手机号={phone}")
|
||
else:
|
||
fail += 1
|
||
error_msg = res_data.get('message') or res_data.get('msg') or '未知错误'
|
||
error_detail = f"错误信息: {error_msg}, 完整响应: {res_data}"
|
||
logger.error(f"客户删除失败: ID={id_customer}, 手机号={phone}, {error_detail}")
|
||
print(f"删除失败: ID={id_customer}, 手机号={phone}, {error_msg}")
|
||
time.sleep(0.2)
|
||
except requests.exceptions.RequestException as e:
|
||
fail += 1
|
||
error_msg = f"网络请求异常: {str(e)}"
|
||
print(f"删除失败: ID={id_customer}, 手机号={phone}, {error_msg}")
|
||
logger.error(f"删除客户时发生网络错误: ID={id_customer}, 手机号={phone}, {error_msg}")
|
||
except Exception as e:
|
||
fail += 1
|
||
error_msg = f"未知错误: {str(e)}"
|
||
print(f"删除失败: ID={id_customer}, 手机号={phone}, {error_msg}")
|
||
logger.error(f"删除客户时发生错误: ID={id_customer}, 手机号={phone}, {error_msg}", exc_info=True)
|
||
|
||
now = datetime.now()
|
||
if 8 <= now.hour <= 20:
|
||
time.sleep(3.5)
|
||
else:
|
||
time.sleep(1.5)
|
||
|
||
logger.info(f"客户删除结果: 成功次数={success}, 失败次数={fail}")
|
||
|
||
msg = update_jiandaoyun(data, f'成功次数{success},失败次数{fail}')
|
||
|
||
if msg.get('msg'):
|
||
approve_workflow(data)
|
||
print('表单已自动提交至下一步')
|
||
except Exception as e:
|
||
logger.error(f"删除客户信息时发生错误: {str(e)}")
|
||
logger.error(traceback.format_exc())
|
||
data["failure_name"] = "删除客户信息后台任务"
|
||
data["failure_details"] = traceback.format_exc()
|
||
execute_failure_handler(data)
|
||
|
||
|
||
|
||
def delete_car_background(data: Dict[str, Any], url: str, cookies: Dict[str, str], header: Dict[str, Any],
|
||
all_page: str):
|
||
"""
|
||
删除客户车辆信息后台任务
|
||
|
||
在后台线程中批量删除客户车辆信息。
|
||
会检查车辆是否有会员卡或最近消费记录,有则跳过删除。
|
||
执行完成后会更新简道云表单并自动提交工作流。
|
||
|
||
Args:
|
||
data: 包含表单ID(api_key)、表单ID(entry_id)、数据ID(data_id)的字典
|
||
url: 获取车辆列表的 API URL
|
||
cookies: 用户登录 F6 系统的 cookies 信息
|
||
header: HTTP 请求头字典,应包含账号登录的请求头
|
||
all_page: 总页数(字符串或整数),用于分页获取车辆列表
|
||
|
||
Returns:
|
||
None
|
||
|
||
注意:
|
||
- 8-20点之间每3.5秒删除一条数据,其余时间每1.5秒删除一条数据
|
||
- 有会员卡或最近消费记录的车辆会被跳过
|
||
- 执行结果会更新到简道云表单
|
||
"""
|
||
try:
|
||
print(cookies)
|
||
success = 0
|
||
fail = 0
|
||
try:
|
||
# 确保 all_page 是一个整数
|
||
all_page = int(all_page)
|
||
|
||
# 获取门店ID
|
||
operate_org_id = get_operate_org_id(cookies)
|
||
if not operate_org_id:
|
||
msg = update_jiandaoyun(data, '删除失败: 未获取到门店信息')
|
||
if msg.get('msg'):
|
||
approve_workflow(data)
|
||
return
|
||
|
||
print(operate_org_id)
|
||
# 获取会员卡列表(提取车辆ID)
|
||
# 注意:需要获取所有车辆的ID,所以不能直接使用 get_card_list
|
||
# 需要自定义提取逻辑,返回所有车辆的ID列表
|
||
card_list_cars = []
|
||
|
||
# 获取第一页,确定总页数
|
||
card_url = f"https://yunxiu.f6car.cn/marketing/card/paging?useStationIdOwnOrgList={operate_org_id}&pageSize=100&pageNo=1"
|
||
card_res = requests.get(url=card_url, cookies=cookies)
|
||
total_card = int(card_res.json().get("data", {}).get("total", 0))
|
||
|
||
if total_card > 0:
|
||
total_page = total_card // 100 + (total_card % 100 > 0)
|
||
for page in tqdm(range(1, total_page + 1), desc="查询会员卡"):
|
||
card_url = (f"https://yunxiu.f6car.cn/marketing/card/paging?useStationIdOwnOrgList={operate_org_id}"
|
||
f"&pageSize=100&pageNo={page}")
|
||
card_res = requests.get(url=card_url, cookies=cookies)
|
||
card_cars_list = card_res.json().get("data", {}).get("data", [])
|
||
|
||
for card_car in card_cars_list:
|
||
if card_car.get("cars") is None:
|
||
continue
|
||
for car in card_car.get("cars", []):
|
||
car_id = car.get("idCar")
|
||
if car_id:
|
||
card_list_cars.append(car_id)
|
||
time.sleep(0.2)
|
||
except Exception as e:
|
||
logger.error(f"获取会员卡列表时发生错误: {e}")
|
||
|
||
itemlist = []
|
||
# 使用 range() 创建一个可迭代的对象
|
||
for page in range(1, all_page + 1):
|
||
json_data = {
|
||
"pageSize": 100,
|
||
"pageNo": page
|
||
}
|
||
|
||
# 获取当前页的数据
|
||
res = requests.post(url=url, cookies=cookies, json=json_data, headers=header)
|
||
res.raise_for_status() # 检查请求是否成功
|
||
response_data = res.json()
|
||
|
||
if 'data' not in response_data or 'data' not in response_data['data']:
|
||
print(f"警告: 页码 {page} 返回的数据格式不正确")
|
||
continue
|
||
|
||
items = response_data['data']['data']
|
||
for item in items:
|
||
itemlist.append(item)
|
||
|
||
for item in tqdm(itemlist, desc="删除车辆信息"):
|
||
car_id = item.get('tmCarInfo', {}).get('pkId')
|
||
customer_id = item.get('tmCustomerInfo', {}).get('pkId')
|
||
consume_last_time = item.get('tmCustomerInfo', {}).get('consumeLastTime')
|
||
|
||
if consume_last_time:
|
||
logger.info(f"{customer_id}最近消费时间: {consume_last_time},跳过删除")
|
||
fail += 1
|
||
continue
|
||
|
||
if car_id in card_list_cars:
|
||
logger.info(f"{customer_id} 存在会员卡,跳过删除")
|
||
fail += 1
|
||
continue
|
||
|
||
if not car_id or not customer_id:
|
||
logger.info(f"页码 {page} 中缺少必要的ID信息")
|
||
fail += 1
|
||
continue
|
||
|
||
try:
|
||
delete_url = (
|
||
f"https://yunxiu.f6car.cn/member/car/deleteCar/{car_id}/{customer_id}"
|
||
)
|
||
delete_res = requests.delete(delete_url, cookies=cookies)
|
||
delete_res.raise_for_status() # 检查删除请求是否成功
|
||
delete_data = delete_res.json()
|
||
|
||
if delete_data.get('data'):
|
||
success += 1
|
||
else:
|
||
fail += 1
|
||
logger.error(
|
||
f"删除失败: 页码 {page}, 车辆ID {car_id}, 客户ID {customer_id},"
|
||
f" 错误信息: {delete_data.get('message', '未知错误')}")
|
||
print(
|
||
f"删除失败: 页码 {page}, 车辆ID {car_id}, 客户ID {customer_id},"
|
||
f" 错误信息: {delete_data.get('message', '未知错误')}")
|
||
|
||
time.sleep(0.2) # 避免过快请求
|
||
except requests.exceptions.RequestException as e:
|
||
fail += 1
|
||
print(f"删除失败: 页码 {page}, 车辆ID {car_id}, 客户ID {customer_id}, 错误信息: {e}")
|
||
logger.error(f"删除失败: 页码 {page}, 车辆ID {car_id}, 客户ID {customer_id}, 错误信息: {e}")
|
||
continue
|
||
|
||
now = datetime.now()
|
||
if 20 <= now.hour <= 8:
|
||
time.sleep(1)
|
||
else:
|
||
time.sleep(3)
|
||
|
||
print(f"完成: 成功删除 {success} 辆车, 失败 {fail} 辆车")
|
||
logger.info(f"完成: 成功删除 {success} 辆车, 失败 {fail} 辆车")
|
||
|
||
|
||
msg = update_jiandaoyun(data, f'成功次数{success},失败次数{fail}')
|
||
|
||
if msg.get('msg'):
|
||
approve_workflow(data)
|
||
print('表单已自动提交至下一步')
|
||
except Exception as e:
|
||
logger.error(f"删除客户车辆信息时发生错误: {str(e)}")
|
||
logger.error(traceback.format_exc())
|
||
data["failure_name"] = "删除客户车辆信息后台任务"
|
||
data["failure_details"] = traceback.format_exc()
|
||
execute_failure_handler(data)
|