异常回访增加错误信息抛出
This commit is contained in:
@@ -248,7 +248,7 @@ class NewExceptionTask:
|
||||
|
||||
# 对整个DataFrame的所有列应用替换函数
|
||||
data_yichang = data_yichang.apply(replace_values)
|
||||
|
||||
error_data= []
|
||||
for index_num, row in data_yichang.iterrows(): # 对过滤后的每一条进行派发
|
||||
try:
|
||||
# 每次循环前清空省市区变量
|
||||
@@ -471,8 +471,14 @@ class NewExceptionTask:
|
||||
res = api_instance.data_batch_create(routine_follow_up_payload)
|
||||
logger.info(f"创建结果:{res}")
|
||||
|
||||
except:
|
||||
except Exception as e:
|
||||
error_task_logger.exception(f"异常服务待办派发执行时发生异常: {e}")
|
||||
error_data.append(row)
|
||||
pass
|
||||
if error_data:
|
||||
error_df = pd.DataFrame(error_data)
|
||||
error_df.to_csv(os.path.join(output_dir, "异常派发错误数据.csv"))
|
||||
common_module.send_task_error(task_start_time = task_start_time,task_name= "异常服务待办派发",error_message="详情见失败文件", df = error_df)
|
||||
# ndf = pd.DataFrame(all_data)
|
||||
# ndf.to_csv(os.path.join(output_dir, "异常派发.csv"))
|
||||
common_module.send_task_status(task_start_time, "异常服务待办派发")
|
||||
|
||||
@@ -6,7 +6,7 @@ import pandas as pd
|
||||
import pymysql
|
||||
from api import API
|
||||
from log_config import configure_task_logger, configure_error_task_logger
|
||||
|
||||
import time
|
||||
|
||||
api_instance = API()
|
||||
# 获取已经配置好的常规日志记录器
|
||||
@@ -168,7 +168,6 @@ class CommonModule:
|
||||
cursor.close()
|
||||
conn.close()
|
||||
|
||||
|
||||
return data_yichang
|
||||
|
||||
except Exception as e:
|
||||
@@ -215,7 +214,6 @@ class CommonModule:
|
||||
error_task_logger.error(f"获取续约待办数据时出错: {e}")
|
||||
return None
|
||||
|
||||
|
||||
def get_jcb_details(self, ):
|
||||
"""
|
||||
从固定的数据库中获取前几天的借车宝。
|
||||
@@ -510,7 +508,6 @@ class CommonModule:
|
||||
error_task_logger.error(f"获取履约表数据时出错: {e}")
|
||||
return None
|
||||
|
||||
|
||||
def get_GroupNotification_details(self, ):
|
||||
"""
|
||||
从f6operation_data_relay数据库中获取短信数据支撑数据。
|
||||
@@ -612,9 +609,11 @@ class CommonModule:
|
||||
task_start_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
CommonModule.send_task_error(task_start_time, "发送任务状态", e)
|
||||
|
||||
def send_task_error(self, task_start_time: str, task_name: str, error_message: str) -> None:
|
||||
def send_task_error(self, task_start_time: str, task_name: str, error_message: str,
|
||||
df: pd.DataFrame = None) -> None:
|
||||
"""
|
||||
将任务失败情况发送到简道云(影响业务数据时调用)
|
||||
:param df: 失败文件
|
||||
:param task_start_time: 任务开始时间(字符串格式:"%Y-%m-%d %H:%M:%S",表示北京时间 UTC+8)
|
||||
:param task_name: 任务名称
|
||||
:param error_message: 失败详情
|
||||
@@ -639,7 +638,26 @@ class CommonModule:
|
||||
task_end_iso = end_time_utc.strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||
task_start_iso = task_start_utc.strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||
|
||||
# 6. 构造请求数据(所有时间以 UTC 格式发送)
|
||||
# 6.上传附件
|
||||
UUid = time.strftime("%Y%m%d%H%M%S", time.localtime())
|
||||
if df is not None:
|
||||
df.to_excel("upload_file.xlsx", index=False)
|
||||
file_path = "upload_file.xlsx"
|
||||
|
||||
up_data = api_instance.get_upload_token(
|
||||
{"api_key": "6694d3c4fcb69ca9a111a6c4", "entry_id": "689ae65da00c17578e27cd74",
|
||||
"transaction_id": UUid})
|
||||
|
||||
upload_url = up_data.get("upload_url")
|
||||
upload_token = up_data.get("upload_token")
|
||||
|
||||
upload_result = api_instance.upload_file(
|
||||
{"upload_url": upload_url, "upload_token": upload_token, "file_path": file_path})
|
||||
upload_key = upload_result.get("key")
|
||||
else:
|
||||
upload_key = ""
|
||||
|
||||
# 7. 构造请求数据(所有时间以 UTC 格式发送)
|
||||
payload = {
|
||||
"api_key": Config.SCHEDULED_TASKS_APP_ID,
|
||||
"entry_id": Config.JDY_TASKS_ERROR_ENTRY_ID,
|
||||
@@ -650,10 +668,12 @@ class CommonModule:
|
||||
"_widget_1744873387502": {"value": task_end_iso}, # UTC 结束时间
|
||||
"_widget_1744873387504": {"value": run_time_sec},
|
||||
"_widget_1754981992215": {"value": error_message}, # 错误信息
|
||||
}
|
||||
"_widget_1764830825356": {"value": [upload_key]}
|
||||
},
|
||||
"transaction_id": UUid
|
||||
}
|
||||
|
||||
# 7. 发送请求
|
||||
# 8. 发送请求
|
||||
response = api_instance.data_batch_create(payload)
|
||||
logger.info(f"任务错误发生成功: {response}")
|
||||
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
2025-11-17 09:27:24,426 - common_module.py - error_task_logger - ERROR - 获取异常明细时出错: can't execute an empty query
|
||||
2025-11-17 17:08:41,207 - Exception_Task.py - error_task_logger - ERROR - 异常服务待办派发执行时发生异常: [Errno 13] Permission denied: 'output\\异常派发.csv'
|
||||
2025-11-18 09:04:21,887 - update_BI_CRM_info.py - error_task_logger - ERROR - 任务简道云海外项目CRM客户档案迁移BI执行失败。
|
||||
2025-11-18 09:06:54,279 - update_BI_CRM_info.py - error_task_logger - ERROR - 任务简道云海外项目CRM客户档案迁移BI执行失败。
|
||||
2025-11-18 09:09:10,231 - update_BI_CRM_info.py - error_task_logger - ERROR - 任务简道云海外项目CRM客户档案迁移BI执行失败。
|
||||
2025-11-18 09:11:15,907 - update_BI_CRM_info.py - error_task_logger - ERROR - 导入数据时发生错误: Failed executing the operation; Python type dict cannot be converted
|
||||
2025-11-18 09:11:16,451 - update_BI_CRM_info.py - error_task_logger - ERROR - 任务简道云海外项目CRM客户档案迁移BI执行失败。
|
||||
2025-11-18 09:14:02,671 - update_BI_CRM_info.py - error_task_logger - ERROR - 任务简道云海外项目CRM客户档案迁移BI执行失败。
|
||||
2025-11-18 09:14:18,875 - update_BI_CRM_info.py - error_task_logger - ERROR - 导入数据时发生错误: 1054 (42S22): Unknown column 'nan' in 'field list'
|
||||
2025-11-18 09:14:19,185 - update_BI_CRM_info.py - error_task_logger - ERROR - 任务简道云海外项目CRM客户档案迁移BI执行失败。
|
||||
2025-11-18 09:15:37,826 - update_BI_CRM_info.py - error_task_logger - ERROR - 导入数据时发生错误: 1054 (42S22): Unknown column 'nan' in 'field list'
|
||||
2025-11-18 09:15:38,068 - update_BI_CRM_info.py - error_task_logger - ERROR - 任务简道云海外项目CRM客户档案迁移BI执行失败。
|
||||
2025-11-18 09:16:52,668 - update_BI_CRM_info.py - error_task_logger - ERROR - 任务简道云海外项目CRM客户档案迁移BI执行失败。
|
||||
2025-11-18 09:17:05,585 - update_BI_CRM_info.py - error_task_logger - ERROR - 导入数据时发生错误: 1054 (42S22): Unknown column 'nan' in 'field list'
|
||||
2025-11-18 09:17:05,912 - update_BI_CRM_info.py - error_task_logger - ERROR - 任务简道云海外项目CRM客户档案迁移BI执行失败。
|
||||
2025-11-27 09:08:41,105 - common_module.py - error_task_logger - ERROR - 获取借车宝NGV明细时出错: Length mismatch: Expected axis has 0 elements, new values have 16 elements
|
||||
2025-11-27 09:08:41,278 - JCB_efficient_car_pickup.py - error_task_logger - ERROR - 接车宝日常派发执行出错:获取接车宝数据失败,返回None
|
||||
2025-12-03 09:35:35,923 - update_molecule_reporting_adjustment_to_bi.py - error_task_logger - ERROR - 任务执行失败: unsupported operand type(s) for //: 'NoneType' and 'int'
|
||||
2025-12-03 09:37:19,719 - update_molecule_reporting_adjustment_to_bi.py - error_task_logger - ERROR - 任务执行失败: unsupported operand type(s) for //: 'NoneType' and 'int'
|
||||
2025-12-03 09:38:02,309 - update_molecule_reporting_adjustment_to_bi.py - error_task_logger - ERROR - 任务执行失败: unsupported operand type(s) for //: 'NoneType' and 'int'
|
||||
2025-12-03 09:39:56,925 - update_molecule_reporting_adjustment_to_bi.py - error_task_logger - ERROR - 任务执行失败: unsupported operand type(s) for //: 'NoneType' and 'int'
|
||||
2025-12-03 09:41:22,721 - update_molecule_reporting_adjustment_to_bi.py - error_task_logger - ERROR - 任务执行失败: unsupported operand type(s) for //: 'NoneType' and 'int'
|
||||
2025-12-03 09:42:57,097 - update_molecule_reporting_adjustment_to_bi.py - error_task_logger - ERROR - 任务执行失败: unsupported operand type(s) for //: 'NoneType' and 'int'
|
||||
2025-12-03 09:45:13,572 - update_molecule_reporting_adjustment_to_bi.py - error_task_logger - ERROR - 任务执行失败: unsupported operand type(s) for //: 'NoneType' and 'int'
|
||||
2025-12-03 09:50:07,647 - update_molecule_reporting_adjustment_to_bi.py - error_task_logger - ERROR - 任务执行失败: unsupported operand type(s) for //: 'NoneType' and 'int'
|
||||
2025-12-03 09:51:28,042 - update_molecule_reporting_adjustment_to_bi.py - error_task_logger - ERROR - 任务执行失败: unsupported operand type(s) for //: 'NoneType' and 'int'
|
||||
2025-12-03 09:55:47,222 - update_molecule_reporting_adjustment_to_bi.py - error_task_logger - ERROR - 任务执行失败: unsupported operand type(s) for //: 'NoneType' and 'int'
|
||||
|
||||
@@ -98,7 +98,7 @@ class DenominatorReportingAdjustment:
|
||||
if id_in_map == field_id:
|
||||
transformed_data[display_name] = value
|
||||
break
|
||||
# print(transformed_data.get("是否上传衡石"))
|
||||
# print(transformed_data.get("是否上传衡石"))# BI上已经实现
|
||||
# if transformed_data.get("是否上传衡石") == "否" or transformed_data.get("是否上传衡石") is None:
|
||||
# continue
|
||||
self.denominator_data_list.append(transformed_data)
|
||||
|
||||
@@ -88,6 +88,7 @@ class MoleculeReportingAdjustment:
|
||||
if id_in_map == field_id:
|
||||
transformed_data[display_name] = value
|
||||
break
|
||||
# BI上已经实现
|
||||
# if transformed_data.get("是否上传衡石") == "否" or transformed_data.get("是否上传衡石") is None:
|
||||
# continue
|
||||
self.molecule_data_list.append(transformed_data)
|
||||
@@ -190,6 +191,7 @@ class MoleculeReportingAdjustment:
|
||||
logger.info(f"获取宜搭数据成功")
|
||||
|
||||
df = pd.DataFrame(self.molecule_data_list)
|
||||
# df.to_csv('molecule_data.csv', index=False)
|
||||
if '归属月份' in df.columns:
|
||||
# 确保是整数类型
|
||||
df['归属月份'] = df['归属月份'].astype('Int64')
|
||||
|
||||
@@ -107,3 +107,17 @@ def configure_detail_logger():
|
||||
task_logger = configure_task_logger()
|
||||
error_logger = configure_error_task_logger()
|
||||
detail_logger = configure_detail_logger()
|
||||
|
||||
# ===== 新增:自动为 error_logger.error 添加 traceback 支持 =====
|
||||
import types
|
||||
import sys
|
||||
|
||||
_original_error = error_logger.error
|
||||
|
||||
def enhanced_error(self, msg, *args, **kwargs):
|
||||
if 'exc_info' not in kwargs:
|
||||
if sys.exc_info()[0] is not None:
|
||||
kwargs['exc_info'] = True
|
||||
return _original_error(msg, *args, **kwargs)
|
||||
|
||||
error_logger.error = types.MethodType(enhanced_error, error_logger)
|
||||
+200
-77
@@ -1,79 +1,202 @@
|
||||
{
|
||||
'data': {
|
||||
'_id': '68d39a00bc54693f3c1e47d4',
|
||||
'creator': {
|
||||
'name': '王兴财',
|
||||
'username': '02480455276729107961',
|
||||
'status': 1,
|
||||
'type': 0,
|
||||
'departments': [
|
||||
177751223
|
||||
],
|
||||
'integrate_id': '02480455276729107961'
|
||||
},
|
||||
'updater': {
|
||||
'name': '王兴财',
|
||||
'username': '02480455276729107961',
|
||||
'status': 1,
|
||||
'type': 0,
|
||||
'departments': [
|
||||
177751223
|
||||
],
|
||||
'integrate_id': '02480455276729107961'
|
||||
},
|
||||
'deleter': None,
|
||||
'createTime': '2025-09-24T07:13:04.967Z',
|
||||
'updateTime': '2025-09-24T07:13:04.967Z',
|
||||
'deleteTime': None,
|
||||
'_widget_1734589432084': '67ebe4846c3e7153268e9004',
|
||||
'_widget_1735268263061': '续约后180天回访',
|
||||
'_widget_1735268263079': '检测单',
|
||||
'_widget_1735268263063': '是',
|
||||
'_widget_1735268263065': '否',
|
||||
'_widget_1735268263067': '',
|
||||
'_widget_1735527329557': '',
|
||||
'_widget_1736414617462': '是',
|
||||
'_widget_1735268263069': '',
|
||||
'_widget_1735268263070': '多次去电未接听,需区域协助联系',
|
||||
'_widget_1735268263071': '',
|
||||
'_widget_1735268263072': '',
|
||||
'_widget_1764293754939': '',
|
||||
'_widget_1735280720550': '10546443563957342000',
|
||||
'_widget_1735268263062': '2025-09-24T07:12:59.124Z',
|
||||
'_widget_1734589782134': {
|
||||
'name': '王兴财',
|
||||
'username': '02480455276729107961',
|
||||
'status': 1,
|
||||
'type': 0,
|
||||
'departments': [
|
||||
177751223
|
||||
],
|
||||
'integrate_id': '02480455276729107961'
|
||||
},
|
||||
'_widget_1743128977141': {
|
||||
'name': '吴间锐',
|
||||
'username': '283227523421943504',
|
||||
'status': 1,
|
||||
'type': 0,
|
||||
'departments': [
|
||||
122323520
|
||||
],
|
||||
'integrate_id': '283227523421943504'
|
||||
},
|
||||
'_widget_1743129332378': {
|
||||
'name': '熊斌',
|
||||
'username': '2530511650927042',
|
||||
'status': 1,
|
||||
'type': 0,
|
||||
'departments': [
|
||||
122323520
|
||||
],
|
||||
'integrate_id': '2530511650927042'
|
||||
},
|
||||
'_widget_1745207582477': '其他',
|
||||
'_widget_1745207582479': '',
|
||||
'_widget_1745207582481': '',
|
||||
'appId': '675b900991ad2491c69389ca',
|
||||
'entryId': '6763bbf657bd8fb76fcb41b2'
|
||||
# 基础信息
|
||||
'date_id': '_widget_1734062123065',
|
||||
'date_fmt': '_widget_1734062123066',
|
||||
'id_own_group': '_widget_1734062123067',
|
||||
'group_name': '_widget_1734062123068',
|
||||
'id_own_org': '_widget_1734062123069',
|
||||
'org_name': '_widget_1734062123070',
|
||||
'org_code': '_widget_1734062123071',
|
||||
'group_grade': '_widget_1734062123072',
|
||||
'org_type': '_widget_1734062123073',
|
||||
'org_status': '_widget_1734062123074',
|
||||
|
||||
# SaaS相关
|
||||
'saas_version': '_widget_1734062123075',
|
||||
'is_wechat': '_widget_1734062123076',
|
||||
'is_mini_app': '_widget_1734062123077',
|
||||
'is_wx_shop': '_widget_1734062123078',
|
||||
'is_camera_service': '_widget_1734062123079',
|
||||
'is_maintenance_service': '_widget_1734062123080',
|
||||
'saas_create_time': '_widget_1734062123081',
|
||||
'expiry_time': '_widget_1734062123082',
|
||||
'saas_use_days': '_widget_1734062123083',
|
||||
'saas_use_year': '_widget_1734062123084',
|
||||
'is_main_org': '_widget_1734062123085',
|
||||
|
||||
# 证照信息
|
||||
'license_code': '_widget_1734062123086',
|
||||
'license_name': '_widget_1734062123087',
|
||||
'org_crm_id': '_widget_1734062123088',
|
||||
|
||||
# 地理信息
|
||||
'province_id': '_widget_1734062123089',
|
||||
'province_name': '_widget_1734062123090',
|
||||
'city_id': '_widget_1734062123091',
|
||||
'city_name': '_widget_1734062123092',
|
||||
'area_id': '_widget_1734062123093',
|
||||
'area_name': '_widget_1734062123094',
|
||||
'region_name': '_widget_1734062123095',
|
||||
'region_short_name': '_widget_1734062123096',
|
||||
'branch_name': '_widget_1734062123097',
|
||||
|
||||
# 车主邦相关
|
||||
'carzone_store_id': '_widget_1734062123098',
|
||||
'carzone_store_name': '_widget_1734062123099',
|
||||
'customer_carzone_id': '_widget_1734062123100',
|
||||
|
||||
# 人员信息
|
||||
'salesmen': '_widget_1734062123101',
|
||||
'area_manager': '_widget_1734062123102',
|
||||
'service_salesmen': '_widget_1734062123103',
|
||||
'impl_principal': '_widget_1734062123104',
|
||||
'service_impl_principal': '_widget_1734062123105',
|
||||
|
||||
# 用户统计
|
||||
'active_user_count': '_widget_1734062123106',
|
||||
'active_user_type': '_widget_1734062123107',
|
||||
'limit_user_count': '_widget_1734062123108',
|
||||
'limit_user_type': '_widget_1734062123109',
|
||||
|
||||
# NGV标记
|
||||
'is_n': '_widget_1734062123110',
|
||||
'is_g': '_widget_1734062123111',
|
||||
'is_v': '_widget_1734062123112',
|
||||
'is_visited': '_widget_1734062123113',
|
||||
'is_active': '_widget_1734062123114',
|
||||
'active_status_fmt': '_widget_1734062123115',
|
||||
|
||||
# 单据统计
|
||||
'bill_count_last_30_day': '_widget_1734062123116',
|
||||
'bill_day_count_last_30_day': '_widget_1734062123117',
|
||||
'bill_day_count_this_month': '_widget_1734062123118',
|
||||
'bill_count_last_7_day': '_widget_1734062123119',
|
||||
'bill_day_count_last_7_day': '_widget_1734062123120',
|
||||
'pv_count': '_widget_1734062123121',
|
||||
'uv_count': '_widget_1734062123122',
|
||||
|
||||
# 每日单据数(1-31天)
|
||||
'bill_count_1d': '_widget_1734062123123',
|
||||
'bill_count_2d': '_widget_1734062123124',
|
||||
'bill_count_3d': '_widget_1734062123125',
|
||||
'bill_count_4d': '_widget_1734062123126',
|
||||
'bill_count_5d': '_widget_1734062123127',
|
||||
'bill_count_6d': '_widget_1734062123128',
|
||||
'bill_count_7d': '_widget_1734062123129',
|
||||
'bill_count_8d': '_widget_1734062123130',
|
||||
'bill_count_9d': '_widget_1734062123131',
|
||||
'bill_count_10d': '_widget_1734062123132',
|
||||
'bill_count_11d': '_widget_1734062123133',
|
||||
'bill_count_12d': '_widget_1734062123134',
|
||||
'bill_count_13d': '_widget_1734062123135',
|
||||
'bill_count_14d': '_widget_1734062123136',
|
||||
'bill_count_15d': '_widget_1734062123137',
|
||||
'bill_count_16d': '_widget_1734062123138',
|
||||
'bill_count_17d': '_widget_1734062123139',
|
||||
'bill_count_18d': '_widget_1734062123140',
|
||||
'bill_count_19d': '_widget_1734062123141',
|
||||
'bill_count_20d': '_widget_1734062123142',
|
||||
'bill_count_21d': '_widget_1734062123143',
|
||||
'bill_count_22d': '_widget_1734062123144',
|
||||
'bill_count_23d': '_widget_1734062123145',
|
||||
'bill_count_24d': '_widget_1734062123146',
|
||||
'bill_count_25d': '_widget_1734062123147',
|
||||
'bill_count_26d': '_widget_1734062123148',
|
||||
'bill_count_27d': '_widget_1734062123149',
|
||||
'bill_count_28d': '_widget_1734062123150',
|
||||
'bill_count_29d': '_widget_1734062123151',
|
||||
'bill_count_30d': '_widget_1734062123152',
|
||||
'bill_count_31d': '_widget_1734062123153',
|
||||
|
||||
# ETL时间
|
||||
'etl_time': '_widget_1734062123154',
|
||||
|
||||
# 业务类型统计
|
||||
'maintain_bill_count_last_30_day': '_widget_1734062123155',
|
||||
'washing_bill_count_last_30_day': '_widget_1734062123156',
|
||||
'maintain_bill_day_count_last_30_day': '_widget_1734062123157',
|
||||
'washing_bill_day_count_last_30_day': '_widget_1734062123158',
|
||||
'retail_bill_count_last_30_day': '_widget_1734062123159',
|
||||
'retail_bill_day_count_last_30_day': '_widget_1734062123160',
|
||||
'purchase_bill_count_last_30_day': '_widget_1734062123161',
|
||||
'purchase_bill_day_count_last_30_day': '_widget_1734062123162',
|
||||
'card_bill_count_last_30_day': '_widget_1734062123163',
|
||||
'card_bill_day_count_last_30_day': '_widget_1734062123164',
|
||||
'gd_sales_bill_count_last_30_day': '_widget_1734062123165',
|
||||
'gd_sales_bill_day_count_last_30_day': '_widget_1734062123166',
|
||||
|
||||
# G标记相关
|
||||
'g_change_flag': '_widget_1734062123167',
|
||||
'saas_package': '_widget_1734062123168',
|
||||
'manage_model': '_widget_1734062123169',
|
||||
|
||||
# 联系信息
|
||||
'contacts': '_widget_1734062123170',
|
||||
'contact_number': '_widget_1734062123171',
|
||||
'contact_mobile': '_widget_1734062123172',
|
||||
|
||||
# G月度统计
|
||||
'g_month_count': '_widget_1734062123173',
|
||||
'g_month_percentage': '_widget_1734062123174',
|
||||
|
||||
# 安装服务
|
||||
'is_install_service': '_widget_1734062123175',
|
||||
'install_create_time': '_widget_1734062123176',
|
||||
'last_end_date': '_widget_1734062123177',
|
||||
'renew_date': '_widget_1734062123178',
|
||||
|
||||
# 连锁信息
|
||||
'is_chain_owner': '_widget_1734062123179',
|
||||
'group_org_count': '_widget_1734062123180',
|
||||
|
||||
# 预警信息
|
||||
'recent_bill_warning_days': '_widget_1734062123181',
|
||||
'g_change_flag_d': '_widget_1734062123182',
|
||||
'g_lost_warning_days': '_widget_1734062123183',
|
||||
|
||||
# SaaS版本
|
||||
'saas_edition_fmt': '_widget_1734062123184',
|
||||
|
||||
# G标记月度(1-6月)
|
||||
'g_flag_1m': '_widget_1734062123185',
|
||||
'g_flag_2m': '_widget_1734062123186',
|
||||
'g_flag_3m': '_widget_1734062123187',
|
||||
'g_flag_4m': '_widget_1734062123188',
|
||||
'g_flag_5m': '_widget_1734062123189',
|
||||
'g_flag_6m': '_widget_1734062123190',
|
||||
'g_flag_day_count': '_widget_1734062123191',
|
||||
|
||||
# 其他标记
|
||||
'add_org_flag': '_widget_1734062123192',
|
||||
'pt': '_widget_1734062123193',
|
||||
|
||||
# 门店属性
|
||||
'org_size': '_widget_1734062123194',
|
||||
'qualification_type_fmt': '_widget_1734062123195',
|
||||
'business_scope_fmt': '_widget_1734062123196',
|
||||
'store_type_fmt': '_widget_1734062123197',
|
||||
'area': '_widget_1734062123198',
|
||||
'station_number': '_widget_1734062123199',
|
||||
'header_type_fmt': '_widget_1734062123200',
|
||||
'org_stage': '_widget_1734062123201',
|
||||
|
||||
# 本月统计
|
||||
'g_count_this_month': '_widget_1734062123202',
|
||||
'saas_customer_type': '_widget_1734062123203',
|
||||
'technician': '_widget_1734062123204',
|
||||
'tmall_maintain_service_status_desc': '_widget_1734062123205',
|
||||
|
||||
# 日期字段(UTC格式)
|
||||
'date_fmt_date': '_widget_1749000071375',
|
||||
'saas_create_time_date': '_widget_1749000071377',
|
||||
'expiry_time_date': '_widget_1749000071382',
|
||||
'install_create_time_date': '_widget_1749000071384',
|
||||
'last_end_date_date': '_widget_1749000071389',
|
||||
'renew_date_date': '_widget_1749000071391',
|
||||
|
||||
# 人员ID字段
|
||||
'area_manager_staff_id': '_widget_1748496855779',
|
||||
'service_salesmen_staff_id': '_widget_1748496855778',
|
||||
'service_impl_principal_staff_id': '_widget_1748496855780',
|
||||
'technician_staff_id': '_widget_1751877712235',
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"id": "initial_id",
|
||||
"metadata": {
|
||||
"collapsed": true,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-12-04T09:43:46.485266Z",
|
||||
"start_time": "2025-12-04T09:43:15.261034Z"
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"from datetime import datetime, timezone, timedelta, date, UTC\n",
|
||||
"import holidays\n",
|
||||
"from config import Config\n",
|
||||
"import psycopg2\n",
|
||||
"import pandas as pd\n",
|
||||
"import pymysql\n",
|
||||
"from api import API\n",
|
||||
"from log_config import configure_task_logger, configure_error_task_logger\n",
|
||||
"import time\n",
|
||||
"\n",
|
||||
"def get_ngv_details(days_back=1):\n",
|
||||
" \"\"\"\n",
|
||||
" 从固定的数据库中获取前几天的NGV明细。\n",
|
||||
" 参数 `days_back` 表示相对于今天的天数偏移量,默认为1(即前一天)。\n",
|
||||
" 返回包含NGV明细的pandas DataFrame。\n",
|
||||
" \"\"\"\n",
|
||||
" try:\n",
|
||||
" # 获得连接\n",
|
||||
" conn = Config.CONN_INFO\n",
|
||||
" conn = psycopg2.connect(**conn)\n",
|
||||
" cursor = conn.cursor()\n",
|
||||
"\n",
|
||||
" # 获取指定天数前的日期\n",
|
||||
" now_time = datetime.now()\n",
|
||||
" target_time = now_time + timedelta(days=-days_back)\n",
|
||||
" target_date_id = int(target_time.strftime('%Y%m%d')) # 获取目标日期\n",
|
||||
"\n",
|
||||
" # sql语句查询\n",
|
||||
" sql = f\"\"\"\n",
|
||||
" SELECT * FROM \"public\".\"holo_ads_report_saas_profile_ngv_detail_d\" WHERE \"date_id\" = '{target_date_id}' ;\n",
|
||||
" \"\"\"\n",
|
||||
"\n",
|
||||
" # 执行语句并获取结果集\n",
|
||||
" cursor.execute(sql)\n",
|
||||
" rows = cursor.fetchall()\n",
|
||||
" all_fields = cursor.description\n",
|
||||
"\n",
|
||||
" # 执行结果转化为dataframe\n",
|
||||
" col = [i[0] for i in all_fields]\n",
|
||||
" data_NGV = pd.DataFrame(rows, columns=col)\n",
|
||||
"\n",
|
||||
" # 尝试自动解析日期时间字符串\n",
|
||||
" time_format = \"%Y-%m-%d %H:%M:%S\"\n",
|
||||
" if 'saas_create_time' in data_NGV.columns:\n",
|
||||
" data_NGV['saas_create_time'] = pd.to_datetime(data_NGV['saas_create_time'], format=time_format,\n",
|
||||
" errors='coerce')\n",
|
||||
" data_NGV['saas_create_time'] = data_NGV['saas_create_time'].dt.strftime('%Y-%m-%d')\n",
|
||||
"\n",
|
||||
" # 关闭游标和连接\n",
|
||||
" cursor.close()\n",
|
||||
" conn.close()\n",
|
||||
"\n",
|
||||
" return data_NGV\n",
|
||||
"\n",
|
||||
" except Exception as e:\n",
|
||||
" print(e)\n",
|
||||
" return None\n",
|
||||
"\n",
|
||||
"data_NGV_j = get_ngv_details(days_back=1)\n",
|
||||
"data_NGV_j1 = get_ngv_details(days_back=2)\n",
|
||||
"\n",
|
||||
"data_NGV_j.to_csv('data_NGV_j.csv', index=False)\n",
|
||||
"data_NGV_j1.to_csv('data_NGV_j1.csv', index=False)"
|
||||
],
|
||||
"outputs": [],
|
||||
"execution_count": 6
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 2
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython2",
|
||||
"version": "2.7.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
+500
@@ -0,0 +1,500 @@
|
||||
import datetime
|
||||
import os
|
||||
import time
|
||||
import requests
|
||||
from api import API
|
||||
from back_ground_module import CommonModule
|
||||
import pandas as pd
|
||||
from log_config import configure_task_logger, configure_error_task_logger
|
||||
import traceback
|
||||
|
||||
api_instance = API()
|
||||
common_module = CommonModule()
|
||||
# start_time = datetime.datetime.now()
|
||||
|
||||
# 获取已经配置好的常规日志记录器
|
||||
logger = configure_task_logger()
|
||||
|
||||
# 获取已经配置好的错误任务日志记录器
|
||||
error_task_logger = configure_error_task_logger()
|
||||
output_dir = "output" # 设置输出目录
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
|
||||
|
||||
class NewExceptionTask:
|
||||
"""
|
||||
SaaS异常回访
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.exception_service_todo = None
|
||||
self.get_feature_usage = None
|
||||
self.saas_create_time = None
|
||||
self.index = None
|
||||
self.date_one = None
|
||||
self.data_yichang_S = None
|
||||
self.date_list = None
|
||||
self.Smart_detection = None
|
||||
self.service_remind = None
|
||||
self.NGV_data_list = None
|
||||
self.permissions_table = None
|
||||
self.staff_id_list = None
|
||||
self.json_list = []
|
||||
self.policy_recognition = None
|
||||
self.widget_list = None
|
||||
self.private_domain = None
|
||||
self.public_domain = None
|
||||
self.public_domain_list = None
|
||||
self.different_industries = None
|
||||
self.different_industries_list = None
|
||||
self.groupnotification = None
|
||||
self.fields_mapping = {
|
||||
"门店名称": "_widget_1748241895830",
|
||||
"联系人": "_widget_1748241895831",
|
||||
"开户时间": "_widget_1748241895839",
|
||||
"门店编码": "_widget_1748241895842",
|
||||
"联系方式": "_widget_1748241895832",
|
||||
"系统版本": "_widget_1748241895850",
|
||||
"公司名称": "_widget_1748241895844",
|
||||
"运营顾问": "_widget_1748246808679",
|
||||
"区域经理": "_widget_1748246808682",
|
||||
"公司等级": "_widget_1748241895846",
|
||||
"运营专家": "_widget_1748246808681",
|
||||
"操作模式E.L/E.S": "_widget_1748241895853",
|
||||
"活跃健康状态变化": "_widget_1748241895829",
|
||||
"初始日": "_widget_1748241895833",
|
||||
"推进日": "_widget_1748241895834",
|
||||
"异常跟进情况描述": "_widget_1748512176640",
|
||||
"异常变化原因": "_widget_1748512176641",
|
||||
"正常使用": "_widget_1748512176643",
|
||||
"门店原因": "_widget_1748512176645",
|
||||
"服务原因": "_widget_1748512176647",
|
||||
"产品原因": "_widget_1748512176649",
|
||||
"未正式切换": "_widget_1748512176651",
|
||||
"跟进状态": "_widget_1748512176655",
|
||||
"是否可激活": "_widget_1758615839701",
|
||||
"是否有续约风险": "_widget_1758615839703",
|
||||
"当前跟进人": "_widget_1748246808678",
|
||||
"激活策略": "_widget_1758615839717",
|
||||
"跟进时间": "_widget_1748512176654",
|
||||
"是否跟进完成": "_widget_1751273412737",
|
||||
"区域客服": "_widget_1748246808680",
|
||||
"大区": "_widget_1748241895847",
|
||||
"省": "_widget_1748241895848",
|
||||
"城市": "_widget_1748241895855",
|
||||
"门店类型": "_widget_1748241895849",
|
||||
"saas客户类型": "_widget_1748241895851",
|
||||
"门店阶段": "_widget_1748241895852",
|
||||
"提交人": "creator",
|
||||
"提交时间": "createTime",
|
||||
"更新时间": "updateTime"
|
||||
}
|
||||
|
||||
def calculate_date_one(self, start_offset=0):
|
||||
"""
|
||||
计算从当前日期(或指定偏移量的日期)开始,往前遍历遇到date_list中日期的次数。
|
||||
|
||||
参数:
|
||||
- start_offset: 从当前日期起始的天数偏移量,默认为0(即今天)。负数表示过去,正数表示未来。
|
||||
|
||||
返回:
|
||||
- date_one: 遍历到date_list中日期的次数。
|
||||
"""
|
||||
jdy_date = datetime.datetime.now().strftime("%Y-%m-%d")
|
||||
jdy_start_time = datetime.datetime.now().strftime("%Y-%m-%d ")
|
||||
# 设置起始日期
|
||||
now_time = datetime.datetime.now() + datetime.timedelta(days=start_offset)
|
||||
|
||||
# 初始化计数器
|
||||
date_one = 1
|
||||
print("当前日期:", now_time.strftime("%Y-%m-%d"))
|
||||
# 检查起始日期是否在date_list中
|
||||
if now_time.strftime("%Y-%m-%d") in self.date_list:
|
||||
date_one = 0
|
||||
print("开始次数:", date_one)
|
||||
|
||||
else:
|
||||
# 遍历日期
|
||||
for i in range(1, 10):
|
||||
new_date = now_time + datetime.timedelta(days=-i)
|
||||
new_date_str = new_date.strftime("%Y-%m-%d")
|
||||
print("遍历日期:", new_date_str)
|
||||
if new_date_str in self.date_list:
|
||||
date_one += 1
|
||||
print("节假日期:", new_date_str)
|
||||
else:
|
||||
break
|
||||
|
||||
print("遍历次数:", date_one)
|
||||
return date_one
|
||||
|
||||
@staticmethod
|
||||
def download_url_content(url, save_path):
|
||||
"""
|
||||
下载指定 URL 的内容并保存到本地文件。
|
||||
|
||||
:param url: 要下载内容的 URL
|
||||
:param save_path: 保存文件的路径
|
||||
"""
|
||||
try:
|
||||
# 发送 GET 请求以获取内容
|
||||
response = requests.get(url, stream=True)
|
||||
response.raise_for_status() # 如果响应状态码不是 200,抛出异常
|
||||
|
||||
# 确保保存目录存在
|
||||
os.makedirs(os.path.dirname(save_path), exist_ok=True)
|
||||
|
||||
# 将内容写入文件
|
||||
with open(save_path, 'wb') as file:
|
||||
for chunk in response.iter_content(chunk_size=8192): # 分块写入,避免占用过多内存
|
||||
if chunk: # 过滤掉空块
|
||||
file.write(chunk)
|
||||
|
||||
print(f"文件已成功保存到 {save_path}")
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"下载失败: {e}")
|
||||
except Exception as e:
|
||||
print(f"发生错误: {e}")
|
||||
|
||||
def load_all_data(self):
|
||||
"""加载所有必要的数据表"""
|
||||
# 省市区人员关系表
|
||||
payload = {"api_key": "675b900991ad2491c69389ca", "entry_id": "676512ac3e54dc3159460c0a"}
|
||||
json_dict = api_instance.entry_data_list(payload)
|
||||
self.json_list = json_dict.get("data")
|
||||
|
||||
# 获取简道云员工id
|
||||
payload = {"api_key": "6694d3c4fcb69ca9a111a6c4",
|
||||
"entry_id": "6769204a1902c9341340a1bc",
|
||||
}
|
||||
staff_id = api_instance.entry_data_list(payload)
|
||||
self.staff_id_list = staff_id.get("data") # api请求格式,将数据封装在data字典里
|
||||
|
||||
# 获取NGV数据
|
||||
payload = {"api_key": "675b900991ad2491c69389ca", "entry_id": "675bb02bd2d53c2034c665e4"}
|
||||
self.NGV_data_list = api_instance.entry_data_list(payload).get("data", [])
|
||||
# print("NGV获取后的类型:", type(self.NGV_data_list))
|
||||
|
||||
# 获取异常服务待办(添加过滤进行中的订单)
|
||||
payload = {"api_key": "675b900991ad2491c69389ca", "entry_id": "68340de79f116c0b66b6b0cc",
|
||||
"filter": {"rel": "and",
|
||||
"cond": [{"field": "flowState", "type": "flowstate", "method": "eq", "value": [0]}]}}
|
||||
self.exception_service_todo = api_instance.entry_data_list(payload).get("data", [])
|
||||
# print(self.exception_service_todo)
|
||||
|
||||
@staticmethod
|
||||
def build_index(json_list):
|
||||
index = {}
|
||||
for json_item in json_list:
|
||||
try:
|
||||
key = (json_item['_widget_1734677164861'], json_item['_widget_1734677164862'],
|
||||
json_item['_widget_1734677164863']) # 省市区
|
||||
if '_widget_1734677164870' not in json_item: # 异常回访客服
|
||||
raise KeyError("缺少 '异常回访客服' 键")
|
||||
index[key] = json_item
|
||||
except KeyError as e:
|
||||
print(f"警告:{e},跳过该条记录: {json_item}")
|
||||
continue
|
||||
print('index', index)
|
||||
return index
|
||||
|
||||
@staticmethod
|
||||
def find_customer_service(province_name, city_name, area_name, index):
|
||||
key = (province_name, city_name, area_name)
|
||||
# print(index)
|
||||
if key not in index:
|
||||
return "数据缺失: 未找到对应的异常回访客服"
|
||||
|
||||
return index[key]
|
||||
|
||||
@staticmethod
|
||||
def get_staff_id(row_item, name):
|
||||
"""辅助函数,用于获取员工ID"""
|
||||
if str(row_item["_widget_1734942794144"]) == str(name): # 检查姓名是否匹配
|
||||
return row_item["_widget_1734942794145"] # 返回员工ID
|
||||
return None
|
||||
|
||||
def assign_customer_service(self, province_name, city_name, area_name, index):
|
||||
"""根据省市区派发给异常回访客服"""
|
||||
# try:
|
||||
customer_service_info = self.find_customer_service(province_name, city_name, area_name, index)
|
||||
customer_service = customer_service_info.get('_widget_1734677164870', {}).get('username') # 异常回访客服
|
||||
return customer_service
|
||||
# except Exception as e:
|
||||
# print(f"Error finding customer service: {e}")
|
||||
# return "分配失败,请检查", "分配失败,请检查", "分配失败,请检查"
|
||||
|
||||
def main(self):
|
||||
|
||||
task_start_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
all_data = []
|
||||
try:
|
||||
self.load_all_data()
|
||||
|
||||
data = pd.read_excel(fr"C:\Users\zy187\Desktop\钉钉文件\异常待办数据(异常的有10条).xlsx", sheet_name="Sheet2")
|
||||
self.data_yichang_S = pd.DataFrame() if data is None or data.empty else data.astype(str)
|
||||
self.index = self.build_index(self.json_list)
|
||||
|
||||
logger.info("开始运行SaaS异常回访")
|
||||
if self.data_yichang_S.empty:
|
||||
logger.info("未获取到数据或数据为空")
|
||||
common_module.send_task_status(task_start_time, "异常服务待办派发")
|
||||
return
|
||||
|
||||
data_yichang = self.data_yichang_S.copy()
|
||||
|
||||
# data_yichang.to_csv(os.path.join(output_dir,"data_yichang.csv"), index=False)
|
||||
|
||||
def replace_values(series):
|
||||
# 使用条件判断来进行替换
|
||||
return series.apply(lambda x: '' if pd.isna(x) or x in ['NA', 'None', ''] else x)
|
||||
|
||||
# 对整个DataFrame的所有列应用替换函数
|
||||
data_yichang = data_yichang.apply(replace_values)
|
||||
|
||||
error_data = []
|
||||
|
||||
for index_num, row in data_yichang.iterrows(): # 对过滤后的每一条进行派发
|
||||
try:
|
||||
# 每次循环前清空省市区变量
|
||||
province_name = None
|
||||
city_name = None
|
||||
area_name = None
|
||||
|
||||
is_pass = False
|
||||
for exception_service in self.exception_service_todo:
|
||||
# 通过查询筛选进行中的逻辑
|
||||
if exception_service['_widget_1748241895842'] == row['org_code']:
|
||||
is_pass = True
|
||||
break
|
||||
|
||||
if is_pass:
|
||||
logger.info(f"已存在待办,跳过该条记录: {row}")
|
||||
continue
|
||||
|
||||
payload_dict = {}
|
||||
|
||||
distribution_date = datetime.datetime.now(datetime.timezone.utc)
|
||||
distribution_date = distribution_date.strftime('%Y-%m-%dT%H:%M:%S.%f')[:-3] + 'Z'
|
||||
|
||||
date_obj1 = datetime.datetime.strptime(row["init_day"], "%Y%m%d").strftime("%Y-%m-%d")
|
||||
date_obj2 = datetime.datetime.strptime(row["push_day"], "%Y%m%d").strftime("%Y-%m-%d")
|
||||
|
||||
NGV_roles = {
|
||||
'service_impl_principal': row['service_impl_principal'], # 运营负责人
|
||||
'area_manager': row['area_manager'], # 区域经理
|
||||
'technician': row['technician'], # 运营专家
|
||||
}
|
||||
for role, name in NGV_roles.items(): # 寻找对应的员工ID
|
||||
for row_item in self.staff_id_list:
|
||||
staff_id = self.get_staff_id(row_item, name)
|
||||
if staff_id:
|
||||
NGV_roles[role] = staff_id
|
||||
break # 找到后退出循环
|
||||
else:
|
||||
NGV_roles[role] = None # 如果没有找到对应的员工ID
|
||||
relationship_manager, area_manager, technician = [NGV_roles[role] for role in
|
||||
['service_impl_principal',
|
||||
'area_manager',
|
||||
'technician']]
|
||||
|
||||
UUid = time.strftime("%Y%m%d%H%M%S", time.localtime())
|
||||
|
||||
NGV_data_id = None
|
||||
reason = None
|
||||
create_exception = None
|
||||
create_date = None
|
||||
|
||||
# 优先从 data_yichang_S 获取省市区信息
|
||||
province_name = row.get('province_name')
|
||||
city_name = row.get('city_name')
|
||||
area_name = row.get('area_name') if 'area_name' in row else row.get('district_name')
|
||||
|
||||
# 检查省市区是否完整(省市区是一体的,任意一个缺失就需要从NGV获取)
|
||||
use_ngv_location = False
|
||||
if (not province_name or province_name in ['', 'None', 'NA'] or
|
||||
not city_name or city_name in ['', 'None', 'NA'] or
|
||||
not area_name or area_name in ['', 'None', 'NA']):
|
||||
use_ngv_location = True
|
||||
logger.info(f"门店 {row['org_code']} 的省市区信息不完整,将从NGV_data_list获取")
|
||||
|
||||
# 获取关联数据
|
||||
for NGV_Data in self.NGV_data_list:
|
||||
# NGV_Data = NGV_Data.get("data")
|
||||
if row["org_code"] == NGV_Data.get("_widget_1734062123071"): # 门店编码
|
||||
NGV_data_id = NGV_Data.get("_id")
|
||||
|
||||
# 如果需要从 NGV_data_list 获取省市区信息
|
||||
if use_ngv_location:
|
||||
province_name = NGV_Data.get("_widget_1734062123090")
|
||||
city_name = NGV_Data.get("_widget_1734062123092")
|
||||
area_name = NGV_Data.get("_widget_1734062123094")
|
||||
logger.info(
|
||||
f"【从NGV获取省市区】门店 {row['org_code']}: {province_name}, {city_name}, {area_name}")
|
||||
|
||||
# 门店原因
|
||||
reason = NGV_Data.get("_widget_1758617393828")
|
||||
logger.info(f"获取关联数据成功:{NGV_data_id}, {province_name}, {city_name}, {area_name}")
|
||||
# 是否生成异常待办
|
||||
create_exception = NGV_Data.get("_widget_1758769279995")
|
||||
# 获取上线日期(文本)# 202512.3改为开户日
|
||||
create_date = NGV_Data.get("_widget_1734062123081")
|
||||
break # 找到匹配的数据后退出循环
|
||||
|
||||
# 判断门店原因
|
||||
# if reason in ["门店倒闭", "门店转让", "加盟其他连锁","切换竞品","虚拟门店","重新开户","已退款","二套系统"]:
|
||||
# continue
|
||||
|
||||
# 判断是否继续生成异常待办
|
||||
if create_exception == "否":
|
||||
continue
|
||||
# 新增:检查 create_date_str 是否存在且有效
|
||||
if not create_date:
|
||||
logger.warning("上线日期为空,跳过该记录")
|
||||
continue
|
||||
|
||||
# 定义可能的日期格式(灵活应对不同格式)
|
||||
date_formats = [
|
||||
"%Y-%m-%d %H:%M:%S", # 含时间
|
||||
"%Y-%m-%d", # 仅日期
|
||||
"%Y/%m/%d",
|
||||
"%Y/%m/%d %H:%M:%S"
|
||||
]
|
||||
|
||||
parsed_date = None
|
||||
for fmt in date_formats:
|
||||
try:
|
||||
parsed_date = datetime.datetime.strptime(create_date.strip(), fmt).date()
|
||||
logger.debug(f"使用格式 {fmt} 成功解析日期: {parsed_date}")
|
||||
break
|
||||
except ValueError:
|
||||
continue
|
||||
|
||||
if parsed_date is None:
|
||||
logger.error(f"无法解析上线日期: '{create_date}',支持的格式: %Y-%m-%d, %Y-%m-%d %H:%M:%S 等")
|
||||
continue # 解析失败,跳过
|
||||
|
||||
# 使用解析后的日期进行判断
|
||||
now_date = datetime.date.today()
|
||||
delta = now_date - parsed_date
|
||||
days_diff = delta.days
|
||||
|
||||
if days_diff > 30:
|
||||
logger.info(f"上线日期 {parsed_date} 超过30天({days_diff}天),生成待办")
|
||||
# ✅ 继续后续待办创建逻辑
|
||||
else:
|
||||
logger.info(f"上线日期 {parsed_date} 在30天内,跳过处理")
|
||||
continue
|
||||
|
||||
if not NGV_data_id:
|
||||
logger.warning(f"未找到关联数据,请检查门店编码: {row['org_code']}")
|
||||
|
||||
logger.info(f"【待办创建】门店 {row['org_code']} 创建待办")
|
||||
|
||||
# 根据省市区派发给异常回访客服
|
||||
# 检查省市区是否都有值,如果有任何一个为空,则客服为空
|
||||
if (not province_name or province_name in ['', 'None', 'NA'] or
|
||||
not city_name or city_name in ['', 'None', 'NA'] or
|
||||
not area_name or area_name in ['', 'None', 'NA']):
|
||||
customer_service = None
|
||||
logger.warning(f"【省市区信息缺失】门店 {row['org_code']} 省市区信息不完整,异常回访客服设置为空")
|
||||
logger.warning(f"省: {province_name}, 市: {city_name}, 区: {area_name}")
|
||||
else:
|
||||
customer_service = self.assign_customer_service(province_name, city_name, area_name, self.index)
|
||||
logger.info(f"【派发客服】门店 {row['org_code']} 派发给客服: {customer_service}")
|
||||
|
||||
payload_dict.update({
|
||||
"_widget_1748241895829": {"value": row["health_warning_info"]}, # 活跃健康状态变化
|
||||
|
||||
"_widget_1748241895830": {"value": row["org_name"]}, # 门店名称
|
||||
|
||||
"_widget_1748241895831": {"value": row["contacts"]}, # 联系人
|
||||
|
||||
"_widget_1748241895832": {"value": row['contact_mobile']}, # 联系方式
|
||||
|
||||
"_widget_1748241895833": {
|
||||
"value": int(time.mktime(time.strptime(date_obj1, "%Y-%m-%d")) * 1000) if row[
|
||||
"init_day"] != '' else ''},
|
||||
# 初始日
|
||||
|
||||
"_widget_1748241895834": {
|
||||
"value": int(time.mktime(time.strptime(date_obj2, "%Y-%m-%d")) * 1000) if row[
|
||||
"push_day"] != '' else ''},
|
||||
# 推进日
|
||||
|
||||
"_widget_1748246808678": {"value": customer_service}, # 当前跟进人
|
||||
# "_widget_1748246808678": {"value": "083726094935447433"}, # 当前跟进人
|
||||
|
||||
"_widget_1748246808679": {"value": relationship_manager}, # 运营负责人
|
||||
|
||||
"_widget_1748246808680": {"value": customer_service}, # 区域客服
|
||||
|
||||
"_widget_1748241895839": {
|
||||
"value": int(time.mktime(time.strptime(row["saas_create_time"], "%Y-%m-%d")) * 1000) if row[
|
||||
"saas_create_time"] != '' else ''},
|
||||
# 开户时间
|
||||
|
||||
"_widget_1748246808681": {"value": technician}, # 技术专家
|
||||
|
||||
"_widget_1748246808682": {"value": area_manager}, # 区域经理
|
||||
|
||||
"_widget_1748241895842": {"value": row['org_code']}, # 门店编码
|
||||
|
||||
"_widget_1748241895844": {"value": row['group_name']}, # 公司名称
|
||||
|
||||
"_widget_1748241895846": {"value": row['group_grade']}, # 公司等级
|
||||
|
||||
"_widget_1748241895847": {"value": row['region_name']}, # 大区
|
||||
|
||||
"_widget_1748241895848": {"value": row['province_name']}, # 省
|
||||
|
||||
"_widget_1748241895849": {"value": row['org_type']}, # 门店类型
|
||||
|
||||
"_widget_1748241895850": {"value": row['saas_edition_fmt']}, # 系统版本
|
||||
|
||||
"_widget_1748241895851": {"value": row['saas_customer_type']}, # saas客户类型
|
||||
|
||||
"_widget_1748241895852": {"value": row['org_stage']}, # 门店阶段
|
||||
|
||||
"_widget_1748241895853": {"value": row['contact_mobile']}, # 操作模式E.L/E.S
|
||||
|
||||
"_widget_1748241895855": {"value": row['city_name']}, # 城市
|
||||
|
||||
"_widget_1748247754304": {"value": NGV_data_id}, # 数据id
|
||||
|
||||
"_widget_1748512176655": {"value": "未处理"}, # 跟进状态
|
||||
|
||||
})
|
||||
|
||||
routine_follow_up_payload = {
|
||||
"api_key": "675b900991ad2491c69389ca",
|
||||
"entry_id": "68340de79f116c0b66b6b0cc", # 异常服务跟进待办
|
||||
"is_start_workflow": "true",
|
||||
"data": payload_dict,
|
||||
"transaction_id": UUid
|
||||
}
|
||||
all_data.append(routine_follow_up_payload)
|
||||
|
||||
res = api_instance.data_batch_create(routine_follow_up_payload)
|
||||
logger.info(f"创建结果:{res}")
|
||||
|
||||
except Exception as e :
|
||||
error_task_logger.error(f"异常服务待办派发执行时发生异常: {e}")
|
||||
error_data.append(row)
|
||||
pass
|
||||
error_df = pd.DataFrame(error_data)
|
||||
error_df.to_csv(os.path.join(output_dir, "异常派发错误数据.csv"))
|
||||
common_module.send_task_error(task_start_time = task_start_time,task_name= "异常服务待办派发",error_message="详情见失败文件", df = error_df)
|
||||
# ndf = pd.DataFrame(all_data)
|
||||
# ndf.to_csv(os.path.join(output_dir, "异常派发.csv"))
|
||||
common_module.send_task_status(task_start_time, "异常服务待办派发")
|
||||
except Exception as e:
|
||||
error_task_logger.error(f"异常服务待办派发执行时发生异常: {e}")
|
||||
common_module.send_task_error(task_start_time, "异常服务待办派发", str(e))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
start = NewExceptionTask()
|
||||
start.main()
|
||||
+1
-1
@@ -19,7 +19,7 @@ error_task_logger = configure_error_task_logger()
|
||||
output_dir = "output" # 设置输出目录
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
|
||||
data = common_module.get_yichang_details(days_back=3)
|
||||
data = common_module.get_yichang_details(days_back=1)
|
||||
|
||||
df = pd.DataFrame(data)
|
||||
df.to_excel(os.path.join(output_dir, "异常待办数据.xlsx"), index=False)
|
||||
|
||||
Reference in New Issue
Block a user