Files
saas/test/异常回访待办问题排查.ipynb

159 lines
6.8 KiB
Plaintext

{
"cells": [
{
"cell_type": "code",
"id": "initial_id",
"metadata": {
"collapsed": true,
"ExecuteTime": {
"end_time": "2026-01-07T02:17:11.661841100Z",
"start_time": "2026-01-07T02:17:11.600589500Z"
}
},
"source": [
"from back_ground_module import CommonModule\n",
"from api import API\n",
"from log_config import configure_task_logger, configure_error_task_logger\n",
"from datetime import datetime, timedelta, timezone\n",
"import pandas as pd\n",
"import os\n",
"\n",
"# 获取已经配置好的常规日志记录器\n",
"logger = configure_task_logger()\n",
"# 获取已经配置好的错误任务日志记录器\n",
"error_task_logger = configure_error_task_logger()\n",
"# 保存为CSV文件\n",
"output_dir = \"output\" # 设置输出目录\n",
"# 创建输出目录(如果不存在)\n",
"import os\n",
"\n",
"os.makedirs(output_dir, exist_ok=True)\n",
"common_module = CommonModule()\n",
"api_instance = API()\n",
"\n",
"data_JCB = common_module.get_jcb_details()\n",
"current_local = datetime.now() + timedelta(days=-1) # tz-naive,代表本地时间\n",
"current_date_str = current_local.strftime(\"%Y-%m-%d\")\n",
"# 计算30天前的本地日期(用于开户日判断)\n",
"thirty_days_ago_local = (current_local - timedelta(days=30)).date()\n",
"payload = {\"api_key\": \"6717470a0b3975ef583c6df1\",\n",
" \"entry_id\": \"67174710da507490d8ac12c1\",\n",
" }\n",
"daily_revisit = api_instance.entry_data_list(payload)\n",
"daily_revisit_list = daily_revisit.get(\"data\") # api请求格式,将数据封装在data字典里\n",
"abnormal_data = []\n",
"for index, row in data_JCB.iterrows():\n",
" try:\n",
" # 开户日是本地日期字符串,解析为 date 对象\n",
" open_date = datetime.strptime(str(row['开户日']), \"%Y-%m-%d\").date()\n",
" except (ValueError, TypeError):\n",
" continue # 跳过无效日期\n",
"\n",
" if (\n",
" open_date < thirty_days_ago_local\n",
" and row['近30天开单天数'] == 0\n",
" and row['客户状态'] == \"留存\"\n",
" ):\n",
" new_row = row.copy()\n",
" new_row[\"日期\"] = open_date.strftime(\"%Y-%m-%d\")\n",
" abnormal_data.append(new_row)\n",
"\n",
"abnormal_data = pd.DataFrame(abnormal_data) if abnormal_data else pd.DataFrame()\n",
"\n",
"if not abnormal_data.empty:\n",
" abnormal_data[\"表单类型\"] = \"异常待办\"\n",
" abnormal_data[\"派发日期\"] = current_date_str\n",
"\n",
" # 清洗手机号(仅去除浮点型 .0)\n",
" def clean_phone(x):\n",
" if pd.isna(x) or x == \"\" or x == \"None\":\n",
" return \"\"\n",
" s = str(x)\n",
" if s.endswith('.0') and s[:-2].isdigit():\n",
" return s[:-2]\n",
" return s\n",
"\n",
" abnormal_data['联系手机号'] = abnormal_data['联系手机号'].apply(clean_phone)\n",
"\n",
"# 构建云端已派发记录 DataFrame\n",
"df_cloud = pd.DataFrame([\n",
" {\n",
" \"数据id\": item.get(\"_id\", \"\"),\n",
" \"账号\": item.get(\"_widget_1739258942667\", \"\"),\n",
" \"提交时间\": item.get(\"createTime\", \"\"),\n",
" \"表单类型\": item.get(\"_widget_1739951204545\", \"\")\n",
" }\n",
" for item in daily_revisit_list\n",
"])\n",
"\n",
"recent_accounts = set()\n",
"if not df_cloud.empty and not abnormal_data.empty:\n",
" # 将 createTime 转为 UTC 时间(强制统一时区)\n",
" df_cloud[\"提交时间\"] = pd.to_datetime(df_cloud[\"提交时间\"], utc=True, errors=\"coerce\")\n",
" df_cloud = df_cloud.dropna(subset=[\"提交时间\"])\n",
"\n",
" # 筛选“异常待办”\n",
" df_abnormal_cloud = df_cloud[df_cloud[\"表单类型\"] == \"异常待办\"]\n",
"\n",
" if not df_abnormal_cloud.empty:\n",
" # 每个账号保留最新一条\n",
" df_recent = df_abnormal_cloud.sort_values(\"提交时间\").groupby(\"账号\", as_index=False).tail(1)\n",
"\n",
" current_utc = datetime.now(timezone.utc)\n",
" cutoff_utc = pd.Timestamp(current_utc) - pd.Timedelta(days=30)\n",
"\n",
" # 安全比较:两边都是 UTC\n",
" recent_accounts = set(df_recent[df_recent[\"提交时间\"] > cutoff_utc][\"账号\"])\n",
"\n",
"# 剔除已派发账号 + 过滤有效手机号\n",
"if not abnormal_data.empty:\n",
" abnormal_data = abnormal_data[\n",
" (~abnormal_data[\"账号\"].isin(recent_accounts)) &\n",
" (abnormal_data[\"联系手机号\"].notna()) &\n",
" (abnormal_data[\"联系手机号\"] != \"\") &\n",
" (abnormal_data[\"联系手机号\"] != \"None\")\n",
" ]\n",
"\n",
"# # 保存结果\n",
"output_path = os.path.join(output_dir, \"异常待办1.csv\")\n",
"abnormal_data.to_csv(output_path, index=False)"
],
"outputs": [
{
"ename": "ModuleNotFoundError",
"evalue": "No module named 'back_ground_module'",
"output_type": "error",
"traceback": [
"\u001B[31m---------------------------------------------------------------------------\u001B[39m",
"\u001B[31mModuleNotFoundError\u001B[39m Traceback (most recent call last)",
"\u001B[36mCell\u001B[39m\u001B[36m \u001B[39m\u001B[32mIn[3]\u001B[39m\u001B[32m, line 1\u001B[39m\n\u001B[32m----> \u001B[39m\u001B[32m1\u001B[39m \u001B[38;5;28;01mfrom\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[34;01mback_ground_module\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[38;5;28;01mimport\u001B[39;00m CommonModule\n\u001B[32m 2\u001B[39m \u001B[38;5;28;01mfrom\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[34;01mapi\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[38;5;28;01mimport\u001B[39;00m API\n\u001B[32m 3\u001B[39m \u001B[38;5;28;01mfrom\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[34;01mlog_config\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[38;5;28;01mimport\u001B[39;00m configure_task_logger, configure_error_task_logger\n",
"\u001B[31mModuleNotFoundError\u001B[39m: No module named 'back_ground_module'"
]
}
],
"execution_count": 3
}
],
"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
}