异常派发修复注释

This commit is contained in:
z66
2025-11-18 09:07:56 +08:00
parent b1d4b34d40
commit baa8fe19ac
12 changed files with 589 additions and 8567 deletions
-28
View File
@@ -3,34 +3,6 @@
<component name="CsvFileAttributes">
<option name="attributeMap">
<map>
<entry key="\back_ground_module\1762841002.961643_ngv_data_yesterday.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\back_ground_module\CRM.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\back_ground_module\DF.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\back_ground_module\create_data.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\db\task_queue.csv">
<value>
<Attribute>
+6
View File
@@ -224,6 +224,8 @@ class NewExceptionTask:
def main(self):
task_start_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
all_data =[]
try:
self.load_all_data()
@@ -462,11 +464,15 @@ class NewExceptionTask:
"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:
pass
# 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}")
+3 -1
View File
@@ -144,7 +144,8 @@ class CommonModule:
target_date_id = int(target_time.strftime('%Y%m%d')) # 获取目标日期
# sql语句查询
sql = f"""-- SELECT * FROM "public"."holo_ads_dataservice_saas_org_health_warning" WHERE "pt" = '{target_date_id}' and "org_type" = '一般';"""
sql = f""" SELECT * FROM "public"."holo_ads_dataservice_saas_org_health_warning" WHERE "pt" = '{target_date_id}' and "org_type" = '一般';"""
# sql = f""" SELECT * FROM "public"."holo_ads_dataservice_saas_org_health_warning" """
# 执行语句并获取结果集
cursor.execute(sql)
@@ -154,6 +155,7 @@ class CommonModule:
# 执行结果转化为dataframe
col = [i[0] for i in all_fields]
data_yichang = pd.DataFrame(rows, columns=col)
# print(data_yichang.head(10))
# 尝试自动解析日期时间字符串
time_format = "%Y-%m-%d %H:%M:%S"
File diff suppressed because it is too large Load Diff
@@ -21,7 +21,7 @@ error_task_logger = configure_error_task_logger()
class NewServicesRevisit:
"""
新签回访180天
新签回访90、180天
"""
def __init__(self):
+2
View File
@@ -188,7 +188,9 @@ class CRMDataProcessor:
def process_data(self, df):
"""处理CRM数据"""
# 去掉前六列和后两列
df.to_csv("CRM.csv", index=False)
df = df.iloc[:, 6:-2]
print(df)
# 生成URL
base_url = f"https://www.jiandaoyun.com/dashboard/app/{self.api_key}/form/{self.entry_id}/data/"
@@ -46,7 +46,7 @@ USE_CONCURRENT_UPDATE = True # True=并发更新(快),False=串行更新
# 并发线程数(同时执行的更新任务数)
# 建议值:5-20,过大可能被API限流,过小影响速度
# 如果API限流严重,可以降低到3-5
CONCURRENT_WORKERS = 6
CONCURRENT_WORKERS = 4
# 【4. 批量创建配置】
# 是否使用批量创建(批量创建速度快)
@@ -110,6 +110,7 @@ class UpdateAllNGVDataDaily:
logger.info("=" * 60)
logger.info("NGV更新数据任务已完成")
common_module.send_task_status(task_start_time, "NGV更新数据")
logger.info("=" * 60)
except Exception as e:
@@ -247,8 +248,8 @@ class UpdateAllNGVDataDaily:
nowtime = time.time()
# 存储每天获取到的数据
ngv_data_1.to_csv(f"{nowtime}_ngv_data_today.csv", index=False)
ngv_data_2.to_csv(f"{nowtime}_ngv_data_yesterday.csv", index=False)
ngv_data_1.to_csv(f"ngv_data_today.csv", index=False)
ngv_data_2.to_csv(f"ngv_data_yesterday.csv", index=False)
# 只保留 org_type 为 "一般" 的记录
ngv_data_1 = ngv_data_1[ngv_data_1['org_type'] == '一般']
@@ -21,7 +21,7 @@ error_task_logger = configure_error_task_logger()
yd_api_instance = YDAPI()
api_instance = API()
common_module = CommonModule()
TOKEN = yd_api_instance.generateToken()
# 配置常量
FORMID = "FORM-WV866IC119W8BZC7AKHAR7VT3FI52W4Q1VBFLD1" # FPO需求提交
@@ -68,6 +68,7 @@ class DenominatorReportingAdjustment:
def get_yida_data(self):
# 获取分母报备数据
TOKEN = yd_api_instance.generateToken()
denominator_data = yd_api_instance.read_processes(token=TOKEN, formUuid=FORMID, page=1, n=100,
appType=appType, systemToken=systemToken)
self.denominator_data_list = []
@@ -204,6 +205,7 @@ class DenominatorReportingAdjustment:
def main(self):
task_start_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
try:
# step1:获取宜搭数据
self.get_yida_data()
logger.info("✅ 获取宜搭数据成功")
@@ -20,8 +20,7 @@ error_task_logger = configure_error_task_logger()
yd_api_instance = YDAPI()
api_instance = API()
common_module = CommonModule()
TOKEN = yd_api_instance.generateToken()
print(TOKEN)
# 配置常量
FORMID = "FORM-VJ866081CVI9E7ALB7WOO7BHPPQW25R99AWFL0" # 分子报备调整
@@ -64,6 +63,7 @@ class MoleculeReportingAdjustment:
def get_yida_data(self):
# 获取分母报备数据
TOKEN = yd_api_instance.generateToken()
molecule_data = yd_api_instance.read_processes(token=TOKEN, formUuid=FORMID, page=1, n=100,
appType=appType, systemToken=systemToken)
self.molecule_data_list = []
@@ -177,6 +177,7 @@ class MoleculeReportingAdjustment:
def main(self):
task_start_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
try:
logger.info(f"开始执行任务")
# step1:获取宜搭数据
self.get_yida_data()
+6
View File
@@ -66,3 +66,9 @@ KeyError: 'data_id'
2025-11-05 16:49:27,058 - 3980554358.py - error_task_logger - ERROR - 任务执行时发生异常: Object of type Timestamp is not JSON serializable
2025-11-05 16:49:59,090 - 2748626104.py - error_task_logger - ERROR - 任务执行时发生异常: Object of type Timestamp is not JSON serializable
2025-11-05 17:03:45,523 - 4224831806.py - error_task_logger - ERROR - 任务执行时发生异常: 'date_fmt'
2025-11-17 09:40:53,054 - common_module.py - error_task_logger - ERROR - 获取异常明细时出错: can't execute an empty query
2025-11-17 09:42:15,554 - common_module.py - error_task_logger - ERROR - 获取异常明细时出错: can't execute an empty query
2025-11-17 09:42:45,482 - common_module.py - error_task_logger - ERROR - 获取异常明细时出错: can't execute an empty query
2025-11-17 09:43:47,620 - common_module.py - error_task_logger - ERROR - 获取异常明细时出错: can't execute an empty query
2025-11-17 09:47:45,814 - common_module.py - error_task_logger - ERROR - 获取异常明细时出错: can't execute an empty query
2025-11-17 09:49:54,823 - common_module.py - error_task_logger - ERROR - 获取异常明细时出错: can't execute an empty query
+554
View File
@@ -0,0 +1,554 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "initial_id",
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import datetime\n",
"import os\n",
"import time\n",
"import requests\n",
"from api import API\n",
"from back_ground_module import CommonModule\n",
"import pandas as pd\n",
"from log_config import configure_task_logger, configure_error_task_logger\n",
"\n",
"api_instance = API()\n",
"common_module = CommonModule()\n",
"# start_time = datetime.datetime.now()\n",
"\n",
"# 获取已经配置好的常规日志记录器\n",
"logger = configure_task_logger()\n",
"\n",
"# 获取已经配置好的错误任务日志记录器\n",
"error_task_logger = configure_error_task_logger()\n",
"output_dir = \"output\" # 设置输出目录\n",
"os.makedirs(output_dir, exist_ok=True)\n",
"\n",
"class NewExceptionTask:\n",
" \"\"\"\n",
" SaaS异常回访\n",
" \"\"\"\n",
"\n",
" def __init__(self):\n",
" self.exception_service_todo = None\n",
" self.get_feature_usage = None\n",
" self.saas_create_time = None\n",
" self.index = None\n",
" self.date_one = None\n",
" self.data_yichang_S = None\n",
" self.date_list = None\n",
" self.Smart_detection = None\n",
" self.service_remind = None\n",
" self.NGV_data_list = None\n",
" self.permissions_table = None\n",
" self.staff_id_list = None\n",
" self.json_list = []\n",
" self.policy_recognition = None\n",
" self.widget_list = None\n",
" self.private_domain = None\n",
" self.public_domain = None\n",
" self.public_domain_list = None\n",
" self.different_industries = None\n",
" self.different_industries_list = None\n",
" self.groupnotification = None\n",
" self.fields_mapping = {\n",
" \"门店名称\": \"_widget_1748241895830\",\n",
" \"联系人\": \"_widget_1748241895831\",\n",
" \"开户时间\": \"_widget_1748241895839\",\n",
" \"门店编码\": \"_widget_1748241895842\",\n",
" \"联系方式\": \"_widget_1748241895832\",\n",
" \"系统版本\": \"_widget_1748241895850\",\n",
" \"公司名称\": \"_widget_1748241895844\",\n",
" \"运营顾问\": \"_widget_1748246808679\",\n",
" \"区域经理\": \"_widget_1748246808682\",\n",
" \"公司等级\": \"_widget_1748241895846\",\n",
" \"运营专家\": \"_widget_1748246808681\",\n",
" \"操作模式E.L/E.S\": \"_widget_1748241895853\",\n",
" \"活跃健康状态变化\": \"_widget_1748241895829\",\n",
" \"初始日\": \"_widget_1748241895833\",\n",
" \"推进日\": \"_widget_1748241895834\",\n",
" \"异常跟进情况描述\": \"_widget_1748512176640\",\n",
" \"异常变化原因\": \"_widget_1748512176641\",\n",
" \"正常使用\": \"_widget_1748512176643\",\n",
" \"门店原因\": \"_widget_1748512176645\",\n",
" \"服务原因\": \"_widget_1748512176647\",\n",
" \"产品原因\": \"_widget_1748512176649\",\n",
" \"未正式切换\": \"_widget_1748512176651\",\n",
" \"跟进状态\": \"_widget_1748512176655\",\n",
" \"是否可激活\": \"_widget_1758615839701\",\n",
" \"是否有续约风险\": \"_widget_1758615839703\",\n",
" \"当前跟进人\": \"_widget_1748246808678\",\n",
" \"激活策略\": \"_widget_1758615839717\",\n",
" \"跟进时间\": \"_widget_1748512176654\",\n",
" \"是否跟进完成\": \"_widget_1751273412737\",\n",
" \"区域客服\": \"_widget_1748246808680\",\n",
" \"大区\": \"_widget_1748241895847\",\n",
" \"省\": \"_widget_1748241895848\",\n",
" \"城市\": \"_widget_1748241895855\",\n",
" \"门店类型\": \"_widget_1748241895849\",\n",
" \"saas客户类型\": \"_widget_1748241895851\",\n",
" \"门店阶段\": \"_widget_1748241895852\",\n",
" \"提交人\": \"creator\",\n",
" \"提交时间\": \"createTime\",\n",
" \"更新时间\": \"updateTime\"\n",
" }\n",
"\n",
" def calculate_date_one(self, start_offset=0):\n",
" \"\"\"\n",
" 计算从当前日期(或指定偏移量的日期)开始,往前遍历遇到date_list中日期的次数。\n",
"\n",
" 参数:\n",
" - start_offset: 从当前日期起始的天数偏移量,默认为0(即今天)。负数表示过去,正数表示未来。\n",
"\n",
" 返回:\n",
" - date_one: 遍历到date_list中日期的次数。\n",
" \"\"\"\n",
" jdy_date = datetime.datetime.now().strftime(\"%Y-%m-%d\")\n",
" jdy_start_time = datetime.datetime.now().strftime(\"%Y-%m-%d \")\n",
" # 设置起始日期\n",
" now_time = datetime.datetime.now() + datetime.timedelta(days=start_offset)\n",
"\n",
" # 初始化计数器\n",
" date_one = 1\n",
" print(\"当前日期:\", now_time.strftime(\"%Y-%m-%d\"))\n",
" # 检查起始日期是否在date_list中\n",
" if now_time.strftime(\"%Y-%m-%d\") in self.date_list:\n",
" date_one = 0\n",
" print(\"开始次数:\", date_one)\n",
"\n",
" else:\n",
" # 遍历日期\n",
" for i in range(1, 10):\n",
" new_date = now_time + datetime.timedelta(days=-i)\n",
" new_date_str = new_date.strftime(\"%Y-%m-%d\")\n",
" print(\"遍历日期:\", new_date_str)\n",
" if new_date_str in self.date_list:\n",
" date_one += 1\n",
" print(\"节假日期:\", new_date_str)\n",
" else:\n",
" break\n",
"\n",
" print(\"遍历次数:\", date_one)\n",
" return date_one\n",
"\n",
" @staticmethod\n",
" def download_url_content(url, save_path):\n",
" \"\"\"\n",
" 下载指定 URL 的内容并保存到本地文件。\n",
"\n",
" :param url: 要下载内容的 URL\n",
" :param save_path: 保存文件的路径\n",
" \"\"\"\n",
" try:\n",
" # 发送 GET 请求以获取内容\n",
" response = requests.get(url, stream=True)\n",
" response.raise_for_status() # 如果响应状态码不是 200,抛出异常\n",
"\n",
" # 确保保存目录存在\n",
" os.makedirs(os.path.dirname(save_path), exist_ok=True)\n",
"\n",
" # 将内容写入文件\n",
" with open(save_path, 'wb') as file:\n",
" for chunk in response.iter_content(chunk_size=8192): # 分块写入,避免占用过多内存\n",
" if chunk: # 过滤掉空块\n",
" file.write(chunk)\n",
"\n",
" print(f\"文件已成功保存到 {save_path}\")\n",
"\n",
" except requests.exceptions.RequestException as e:\n",
" print(f\"下载失败: {e}\")\n",
" except Exception as e:\n",
" print(f\"发生错误: {e}\")\n",
"\n",
" def load_all_data(self):\n",
" \"\"\"加载所有必要的数据表\"\"\"\n",
" # 省市区人员关系表\n",
" payload = {\"api_key\": \"675b900991ad2491c69389ca\", \"entry_id\": \"676512ac3e54dc3159460c0a\"}\n",
" json_dict = api_instance.entry_data_list(payload)\n",
" self.json_list = json_dict.get(\"data\")\n",
"\n",
" # 获取简道云员工id\n",
" payload = {\"api_key\": \"6694d3c4fcb69ca9a111a6c4\",\n",
" \"entry_id\": \"6769204a1902c9341340a1bc\",\n",
" }\n",
" staff_id = api_instance.entry_data_list(payload)\n",
" self.staff_id_list = staff_id.get(\"data\") # api请求格式,将数据封装在data字典里\n",
"\n",
" # 获取NGV数据\n",
" payload = {\"api_key\": \"675b900991ad2491c69389ca\", \"entry_id\": \"675bb02bd2d53c2034c665e4\"}\n",
" self.NGV_data_list = api_instance.entry_data_list(payload).get(\"data\", [])\n",
" # print(\"NGV获取后的类型:\", type(self.NGV_data_list))\n",
"\n",
" # 获取异常服务待办\n",
" payload = {\"api_key\": \"675b900991ad2491c69389ca\", \"entry_id\": \"68340de79f116c0b66b6b0cc\"}\n",
" self.exception_service_todo = api_instance.entry_data_list(payload).get(\"data\", [])\n",
" print(self.exception_service_todo)\n",
"\n",
" @staticmethod\n",
" def build_index(json_list):\n",
" index = {}\n",
" for json_item in json_list:\n",
" try:\n",
" key = (json_item['_widget_1734677164861'], json_item['_widget_1734677164862'],\n",
" json_item['_widget_1734677164863']) # 省市区\n",
" if '_widget_1734677164870' not in json_item: # 异常回访客服\n",
" raise KeyError(\"缺少 '异常回访客服' 键\")\n",
" index[key] = json_item\n",
" except KeyError as e:\n",
" print(f\"警告:{e},跳过该条记录: {json_item}\")\n",
" continue\n",
" print('index', index)\n",
" return index\n",
"\n",
" @staticmethod\n",
" def find_customer_service(province_name, city_name, area_name, index):\n",
" key = (province_name, city_name, area_name)\n",
" # print(index)\n",
" if key not in index:\n",
" return \"数据缺失: 未找到对应的异常回访客服\"\n",
"\n",
" return index[key]\n",
"\n",
" @staticmethod\n",
" def get_staff_id(row_item, name):\n",
" \"\"\"辅助函数,用于获取员工ID\"\"\"\n",
" if str(row_item[\"_widget_1734942794144\"]) == str(name): # 检查姓名是否匹配\n",
" return row_item[\"_widget_1734942794145\"] # 返回员工ID\n",
" return None\n",
"\n",
" def assign_customer_service(self, province_name, city_name, area_name, index):\n",
" \"\"\"根据省市区派发给异常回访客服\"\"\"\n",
" # try:\n",
" customer_service_info = self.find_customer_service(province_name, city_name, area_name, index)\n",
" customer_service = customer_service_info.get('_widget_1734677164870', {}).get('username') # 异常回访客服\n",
" return customer_service\n",
" # except Exception as e:\n",
" # print(f\"Error finding customer service: {e}\")\n",
" # return \"分配失败,请检查\", \"分配失败,请检查\", \"分配失败,请检查\"\n",
"\n",
" def main(self):\n",
"\n",
" task_start_time = datetime.datetime.now().strftime(\"%Y-%m-%d %H:%M:%S\")\n",
" try:\n",
" self.load_all_data()\n",
"\n",
" data = common_module.get_yichang_details(days_back=1)\n",
" self.data_yichang_S = pd.DataFrame() if data is None or data.empty else data.astype(str)\n",
" self.index = self.build_index(self.json_list)\n",
"\n",
" logger.info(\"开始运行SaaS异常回访\")\n",
" if self.data_yichang_S.empty:\n",
" logger.info(\"未获取到数据或数据为空\")\n",
" common_module.send_task_status(task_start_time, \"异常服务待办派发\")\n",
" return\n",
"\n",
" data_yichang = self.data_yichang_S.copy()\n",
" # data_yichang.to_csv(os.path.join(output_dir,\"data_yichang.csv\"), index=False)\n",
"\n",
" def replace_values(series):\n",
" # 使用条件判断来进行替换\n",
" return series.apply(lambda x: '' if pd.isna(x) or x in ['NA', 'None', ''] else x)\n",
"\n",
" # 对整个DataFrame的所有列应用替换函数\n",
" data_yichang = data_yichang.apply(replace_values)\n",
"\n",
" for index_num, row in data_yichang.iterrows(): # 对过滤后的每一条进行派发\n",
" try:\n",
" # 每次循环前清空省市区变量\n",
" province_name = None\n",
" city_name = None\n",
" area_name = None\n",
"\n",
" is_pass = False\n",
" for exception_service in self.exception_service_todo :\n",
" if exception_service['_widget_1748241895842'] == row['org_code'] and exception_service['_widget_1748512176655'] in ['未处理', '处理中']:\n",
" is_pass = True\n",
" break\n",
" if is_pass:\n",
" logger.info(f\"已存在待办,跳过该条记录: {row}\")\n",
" continue\n",
"\n",
" payload_dict = {}\n",
"\n",
" distribution_date = datetime.datetime.now(datetime.timezone.utc)\n",
" distribution_date = distribution_date.strftime('%Y-%m-%dT%H:%M:%S.%f')[:-3] + 'Z'\n",
"\n",
" date_obj1 = datetime.datetime.strptime(row[\"init_day\"], \"%Y%m%d\").strftime(\"%Y-%m-%d\")\n",
" date_obj2 = datetime.datetime.strptime(row[\"push_day\"], \"%Y%m%d\").strftime(\"%Y-%m-%d\")\n",
"\n",
" NGV_roles = {\n",
" 'service_impl_principal': row['service_impl_principal'], # 运营负责人\n",
" 'area_manager': row['area_manager'], # 区域经理\n",
" 'technician': row['technician'], # 运营专家\n",
" }\n",
" for role, name in NGV_roles.items(): # 寻找对应的员工ID\n",
" for row_item in self.staff_id_list:\n",
" staff_id = self.get_staff_id(row_item, name)\n",
" if staff_id:\n",
" NGV_roles[role] = staff_id\n",
" break # 找到后退出循环\n",
" else:\n",
" NGV_roles[role] = None # 如果没有找到对应的员工ID\n",
" relationship_manager, area_manager, technician = [NGV_roles[role] for role in\n",
" ['service_impl_principal',\n",
" 'area_manager',\n",
" 'technician']]\n",
"\n",
" UUid = time.strftime(\"%Y%m%d%H%M%S\", time.localtime())\n",
"\n",
" NGV_data_id = None\n",
" reason = None\n",
" create_exception =None\n",
" create_date = None\n",
"\n",
" # 优先从 data_yichang_S 获取省市区信息\n",
" province_name = row.get('province_name')\n",
" city_name = row.get('city_name')\n",
" area_name = row.get('area_name') if 'area_name' in row else row.get('district_name')\n",
"\n",
" # 检查省市区是否完整(省市区是一体的,任意一个缺失就需要从NGV获取)\n",
" use_ngv_location = False\n",
" if (not province_name or province_name in ['', 'None', 'NA'] or\n",
" not city_name or city_name in ['', 'None', 'NA'] or\n",
" not area_name or area_name in ['', 'None', 'NA']):\n",
" use_ngv_location = True\n",
" logger.info(f\"门店 {row['org_code']} 的省市区信息不完整,将从NGV_data_list获取\")\n",
"\n",
" # 获取关联数据\n",
" for NGV_Data in self.NGV_data_list:\n",
" # NGV_Data = NGV_Data.get(\"data\")\n",
" if row[\"org_code\"] == NGV_Data.get(\"_widget_1734062123071\"): # 门店编码\n",
" NGV_data_id = NGV_Data.get(\"_id\")\n",
"\n",
" # 如果需要从 NGV_data_list 获取省市区信息\n",
" if use_ngv_location:\n",
" province_name = NGV_Data.get(\"_widget_1734062123090\")\n",
" city_name = NGV_Data.get(\"_widget_1734062123092\")\n",
" area_name = NGV_Data.get(\"_widget_1734062123094\")\n",
" logger.info(f\"【从NGV获取省市区】门店 {row['org_code']}: {province_name}, {city_name}, {area_name}\")\n",
"\n",
" # 门店原因\n",
" reason = NGV_Data.get(\"_widget_1758617393828\")\n",
" logger.info(f\"获取关联数据成功:{NGV_data_id}, {province_name}, {city_name}, {area_name}\")\n",
" # 是否生成异常待办\n",
" create_exception = NGV_Data.get(\"_widget_1758769279995\")\n",
" # 获取上线日期(文本)\n",
" create_date = NGV_Data.get(\"_widget_1734062123176\")\n",
" break # 找到匹配的数据后退出循环\n",
"\n",
" # 判断门店原因\n",
" # if reason in [\"门店倒闭\", \"门店转让\", \"加盟其他连锁\",\"切换竞品\",\"虚拟门店\",\"重新开户\",\"已退款\",\"二套系统\"]:\n",
" # continue\n",
"\n",
" # 判断是否继续生成异常待办\n",
" if create_exception == \"否\":\n",
" continue\n",
" # 新增:检查 create_date_str 是否存在且有效\n",
" if not create_date:\n",
" logger.warning(\"上线日期为空,跳过该记录\")\n",
" continue\n",
"\n",
" # 定义可能的日期格式(灵活应对不同格式)\n",
" date_formats = [\n",
" \"%Y-%m-%d %H:%M:%S\", # 含时间\n",
" \"%Y-%m-%d\", # 仅日期\n",
" \"%Y/%m/%d\",\n",
" \"%Y/%m/%d %H:%M:%S\"\n",
" ]\n",
"\n",
" parsed_date = None\n",
" for fmt in date_formats:\n",
" try:\n",
" parsed_date = datetime.datetime.strptime(create_date.strip(), fmt).date()\n",
" logger.debug(f\"使用格式 {fmt} 成功解析日期: {parsed_date}\")\n",
" break\n",
" except ValueError:\n",
" continue\n",
"\n",
" if parsed_date is None:\n",
" logger.error(f\"无法解析上线日期: '{create_date}',支持的格式: %Y-%m-%d, %Y-%m-%d %H:%M:%S 等\")\n",
" continue # 解析失败,跳过\n",
"\n",
" # 使用解析后的日期进行判断\n",
" now_date = datetime.date.today()\n",
" delta = now_date - parsed_date\n",
" days_diff = delta.days\n",
"\n",
" if days_diff > 30:\n",
" logger.info(f\"上线日期 {parsed_date} 超过30天({days_diff}天),生成待办\")\n",
" # ✅ 继续后续待办创建逻辑\n",
" else:\n",
" logger.info(f\"上线日期 {parsed_date} 在30天内,跳过处理\")\n",
" continue\n",
"\n",
"\n",
" if not NGV_data_id:\n",
" logger.warning(f\"未找到关联数据,请检查门店编码: {row['org_code']}\")\n",
"\n",
" # 根据省市区派发给异常回访客服\n",
" # 检查省市区是否都有值,如果有任何一个为空,则客服为空\n",
" if (not province_name or province_name in ['', 'None', 'NA'] or\n",
" not city_name or city_name in ['', 'None', 'NA'] or\n",
" not area_name or area_name in ['', 'None', 'NA']):\n",
" customer_service = None\n",
" logger.warning(f\"【省市区信息缺失】门店 {row['org_code']} 省市区信息不完整,异常回访客服设置为空\")\n",
" logger.warning(f\"省: {province_name}, 市: {city_name}, 区: {area_name}\")\n",
" else:\n",
" customer_service = self.assign_customer_service(province_name, city_name, area_name, self.index)\n",
" logger.info(f\"【派发客服】门店 {row['org_code']} 派发给客服: {customer_service}\")\n",
"\n",
" payload_dict.update({\n",
" \"_widget_1748241895829\": {\"value\": row[\"health_warning_info\"]}, # 活跃健康状态变化\n",
"\n",
" \"_widget_1748241895830\": {\"value\": row[\"org_name\"]}, # 门店名称\n",
"\n",
" \"_widget_1748241895831\": {\"value\": row[\"contacts\"]}, # 联系人\n",
"\n",
" \"_widget_1748241895832\": {\"value\": row['contact_mobile']}, # 联系方式\n",
"\n",
" \"_widget_1748241895833\": {\n",
" \"value\": int(time.mktime(time.strptime(date_obj1, \"%Y-%m-%d\")) * 1000) if row[\n",
" \"init_day\"] != '' else ''},\n",
" # 初始日\n",
"\n",
" \"_widget_1748241895834\": {\n",
" \"value\": int(time.mktime(time.strptime(date_obj2, \"%Y-%m-%d\")) * 1000) if row[\n",
" \"push_day\"] != '' else ''},\n",
" # 推进日\n",
"\n",
" \"_widget_1748246808678\": {\"value\": customer_service}, # 当前跟进人\n",
" # \"_widget_1748246808678\": {\"value\": \"083726094935447433\"}, # 当前跟进人\n",
"\n",
" \"_widget_1748246808679\": {\"value\": relationship_manager}, # 运营负责人\n",
"\n",
" \"_widget_1748246808680\": {\"value\": customer_service}, # 区域客服\n",
"\n",
" \"_widget_1748241895839\": {\n",
" \"value\": int(time.mktime(time.strptime(row[\"saas_create_time\"], \"%Y-%m-%d\")) * 1000) if row[\n",
" \"saas_create_time\"] != '' else ''},\n",
" # 开户时间\n",
"\n",
" \"_widget_1748246808681\": {\"value\": technician}, # 技术专家\n",
"\n",
" \"_widget_1748246808682\": {\"value\": area_manager}, # 区域经理\n",
"\n",
" \"_widget_1748241895842\": {\"value\": row['org_code']}, # 门店编码\n",
"\n",
" \"_widget_1748241895844\": {\"value\": row['group_name']}, # 公司名称\n",
"\n",
" \"_widget_1748241895846\": {\"value\": row['group_grade']}, # 公司等级\n",
"\n",
" \"_widget_1748241895847\": {\"value\": row['region_name']}, # 大区\n",
"\n",
" \"_widget_1748241895848\": {\"value\": row['province_name']}, # 省\n",
"\n",
" \"_widget_1748241895849\": {\"value\": row['org_type']}, # 门店类型\n",
"\n",
" \"_widget_1748241895850\": {\"value\": row['saas_edition_fmt']}, # 系统版本\n",
"\n",
" \"_widget_1748241895851\": {\"value\": row['saas_customer_type']}, # saas客户类型\n",
"\n",
" \"_widget_1748241895852\": {\"value\": row['org_stage']}, # 门店阶段\n",
"\n",
" \"_widget_1748241895853\": {\"value\": row['contact_mobile']}, # 操作模式E.L/E.S\n",
"\n",
" \"_widget_1748241895855\": {\"value\": row['city_name']}, # 城市\n",
"\n",
" \"_widget_1748247754304\": {\"value\": NGV_data_id}, # 数据id\n",
"\n",
" \"_widget_1748512176655\": {\"value\": \"未处理\"}, # 跟进状态\n",
"\n",
" })\n",
"\n",
" routine_follow_up_payload = {\n",
" \"api_key\": \"675b900991ad2491c69389ca\",\n",
" \"entry_id\": \"68340de79f116c0b66b6b0cc\", # 异常服务跟进待办\n",
" \"is_start_workflow\": \"true\",\n",
" \"data\": payload_dict,\n",
" \"transaction_id\": UUid\n",
" }\n",
"\n",
" res = api_instance.data_batch_create(routine_follow_up_payload)\n",
" logger.info(f\"创建结果:{res}\")\n",
" except:\n",
" pass\n",
" common_module.send_task_status(task_start_time, \"异常服务待办派发\")\n",
" except Exception as e:\n",
" error_task_logger.error(f\"异常服务待办派发执行时发生异常: {e}\")\n",
" common_module.send_task_error(task_start_time, \"异常服务待办派发\", str(e))\n",
"\n",
"\n",
"if __name__ == '__main__':\n",
" start = NewExceptionTask()\n",
" start.main()\n"
]
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-11-17T02:17:23.550591Z",
"start_time": "2025-11-17T02:16:33.774564Z"
}
},
"cell_type": "code",
"source": [
"import datetime\n",
"import os\n",
"import time\n",
"import requests\n",
"from api import API\n",
"from back_ground_module import CommonModule\n",
"import pandas as pd\n",
"from log_config import configure_task_logger, configure_error_task_logger\n",
"\n",
"api_instance = API()\n",
"common_module = CommonModule()\n",
"# start_time = datetime.datetime.now()\n",
"\n",
"# 获取已经配置好的常规日志记录器\n",
"logger = configure_task_logger()\n",
"\n",
"# 获取已经配置好的错误任务日志记录器\n",
"error_task_logger = configure_error_task_logger()\n",
"output_dir = \"output\" # 设置输出目录\n",
"os.makedirs(output_dir, exist_ok=True)\n",
"\n",
"from datetime import datetime,timedelta\n",
"for i in range(1,27):\n",
" data = common_module.get_yichang_details(days_back=i)\n",
" time = (datetime.now() - timedelta(days=i)).strftime(\"%Y-%m-%d\")\n",
" data.to_excel(os.path.join(output_dir,f\"异常数据{time}天.xlsx\"),index = False)\n"
],
"id": "3fbb80f75435d56b",
"outputs": [],
"execution_count": 5
}
],
"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
}
+3 -1
View File
@@ -151,7 +151,9 @@ class YDAPI:
try:
res = requests.post(api, headers=headers, json=formData)
res.raise_for_status() # 如果返回状态码不是2xx,抛出异常
logger.info(f"HTTP Status Code: {res.status_code}")
logger.info(f"Response Headers: {dict(res.headers)}")
logger.info(f"Raw Response Text: {res.text}") # 注意:不要在线上环境打印敏感数据!
return res.json()
except requests.exceptions.RequestException as e: